多线程:硬件基础
一、高速缓存
现代CPU的处理性能是远远高于主内存,一次内存读或者写操作的时间内,CPU能够处理上百条指令。为了弥补CPU与内存之间性能的鸿沟,引入高速缓存(Cache)。
高速缓存的性能远远高于主内存,但是容量要小于主内存 。每个处理器都有其独立的高速缓存。有了高速缓存之后,处理器在做内存读写操作时就不必直接与主内存打交道,而是与缓存打交道(从缓存中读或写)。
缓存的数据结构相当于一个散列表,由若干桶和缓存条目组成,缓存条目又可以细分成三个部分:Data Block(缓存行)中存储了从内存中读取的或者将要写入内存的数据;Tag储存了缓存行中数据相应的内存地址的部分信息(内存地址的高位部分比特);Flag用于表示缓存行的状态信息,有哪些中状态值下面会进一步说明。
那么,处理器如果想操作储存在主内存地址A的变量时,具体时如何与缓存打交道的呢?
- 处理器把地址A解码为index,tag,offset三个数据。
- 首先通过index值定位到桶。
- 然后通过tag值比对定位到具体的缓存条目。
- 最后根据offset偏移量的值定位到缓存行中该变量的起始位置。
根据上述步骤如如果能够定位到相应的缓存行且所在缓存条目的Flag值表示缓存条目是有效的,我们就称相应的内存操作产生了缓存命中,相反则称为缓存未命中。
二、缓存一致性协议
多线程共同操作同一个变量的情况下,执行这些线程的处理器都会在其缓存中保存该变量的副本。如果其中一个线程更新了该变量在缓存中的副本,那么其他线程是如果察觉并同步的呢?如果其他线程并未同步变量的更新,并且读取该变量的话就会得到老的数据。为解决这种情况,引入了以中通信机制:缓存一致性协议。
MESI协议将缓存条目的状态划分为:Modified、Exclusive、Shared、Invalid四种。并定义了一组消息用于协调各个处理器的读写内存操作,如下表所示。处理器要执行读写操作时会向总线Bus中发送特定的请求消息,其他处理器嗅探(Snoop也称拦截)总线中由其他处理器所发出的请求消息,并在一定条件下向总线中回复相应的响应消息。
消息名 | 消息类型 | 描述 |
---|---|---|
Read | 请求 | 通知其他处理器,主内存当前处理器正准备读取某个数据。该消息包含待读取数据的内存地址 |
Read Response | 相应 | 该消息相应Read消息,其中包含被请求读取的数据,有可能是来自与其他处理器中的高速缓存提供的,也可能是主内存提供的 |
Invalidate | 请求 | 通知其他处理器将其高速缓存中指定内存地址对应的缓存条目的状态Flag值置为I,即删除指定内存地址的副本数据(逻辑删除) |
Invalidate Acknowledge | 响应 | 接受到Invalidate消息的处理器必须回复该消息,表示删除了其高速缓存上相应的副本数据 |
Read Invalidate | 请求 | 该消息是Read消息和Invalidate消息的组合。作用在通知其他处理器当前处理器准备更新一个数据(Read-Modify-Write)接受到该消息的处理器必须回复Read Response消息和Invalidate消息 |
Writeback | 请求 | 该消息包含需要写入主内存的数据及其对应的内存地址 |
举例:P1,P2两个处理器共享数据S,数据在储存在内存地址A上。
读内存操作流程图:
写内存操作流程图:
三、写缓冲器
由上面的写流程图发现,如果一个处理器想要对进行写内存操作就必须获取相应数据的所有权,也就是该数据的内存地址所对应的缓存条目的状态必须为E或者M,即只有当前处理器的缓存中存储了该数据在内存中的副本。如果不为E或者M,就需要发送Invalidate消息或Read Invalidate消息来致使其他处理器上相应缓存条目失效,从而保证只有当前处理器的缓存中存储了该数据在内存中的副本。这种机制就导致了一旦处理器进行写内存操作且没有相应数据的所有权,就必须在发送了Invalidate消息或Read Invalidate消息之后等待其他所有处理器回复Invalidate Acknowledge消息,而在等待期间,处理器无法继续执行其他命令,降低了处理器的指令执行效率。为解决这种问题,引入了写缓冲器。
写缓冲器(Store Buffer,也被称为Write Buffer),是处理器内部的一个容量比高速缓存还小的储存部件,每个处理器都有其写缓冲器,并且一个处理器无法读取另外一个处理器上的写缓冲器中的内容。
有了写缓冲器后,在进行内存写操作时,如果相应缓存条目的状态不为E或M,当前处理器会将数据先写入写缓冲器中并发送Invalidate消息或Read Invalidate消息。此时当前处理器认为写操作已经完成不会继续等待Invalidate Acknowledge消息从而继续执行其他指令。一旦当前处理器接收到了其他所有处理器针对同一个缓存条目回复的Invalidate Acknowledge消息时,该处理器会将写缓冲器中针对相应地址的写操作的结果写入相应的缓存行中。此时对于其他处理器来说写操作才算是完成的。
存储转发:引入写缓冲器后,处理器在执行读操作时不会直接从缓存中读取数据。而是会先根据相应的地址在写缓冲器中查找是否有相应的条目,如果有则直接将写缓冲器中的数据返回,如果没有后则从缓存中读取数据,以此避免处理器读到旧数据。
来源:https://www.cnblogs.com/stuxi/p/12643198.html