《内存一致性与缓存一致性(第二版)》一书(英文名为A Primer on Memory Consistency and Cache Coherence)隶属于Synthesis Lectures on Computer Architecture系列,面向于学习过基础的计算机体系结构但是想进一步深入了解内存一致性与缓存一致性的读者。
内存一致性与缓存一致性(CMU 18-447 Spring 2022 L24 Cache Coherence)
内存一致性(又称内存一致性模型或内存模型)
首先来看一个直观的例子。一所大学在网上发布其课程表,假设计算机体系结构课程最初被安排在152教室。在开课的前一天,教务处决定将该课移到252教室,并发送了一封电子邮件,要求网站管理员更新在线课程表,几分钟后,教务处向所有这门课的学生发送了一条短信,让他们查看新更新的课程表。不难想象,如果网站管理员太忙,无法立即发布更新信息,那么勤奋的学生收到短信后,立即查看在线课程表,但仍然观察到152教室的(旧)课程表 。尽管在线课程表最终被更新为252教室,而且教务处确实以正确的顺序进行了“写入”操作,但勤奋的学生还是以不同的顺序观察到了课程表,因此去错了上课的教室。
内存一致性模型以load和store的方式定义了正确的共享内存行为。访问内存不确定的行为可能发生在各种共享内存的硬件中,如乱序处理器内核、write buffer、预取、多级缓存中,因此我们有必要确定内存访问行为的正确性。在本书的后面几章会依次介绍顺序一致性、TSO模型、以及“松弛”或“弱”内存一致性模型。
缓存一致性
和之前一样,我们来看一个直观的例子。一个学生检查了在线课程表,发现计算机结构课程在152教室(读取数据),并将此信息复制到手机中(缓存数据)。随后,教务处决定将课程移到252室,更新了在线课程表(写入数据),并通过短信通知学生。注意此时学生手机里的信息现在已经过时了,发生了缓存不一致的情况。如果这时学生按照手机里的信息前往152教室,就会发现走错教室了。
对过时数据的访问是通过缓存一致性协议来避免的,缓存一致性协议在同步发生的时间和方式上存在差异,有两类主要的一致性协议。第一类方法中,一致性协议确保写入的内容同步传播到各个缓存中;第二类方法中,一致性协议将写入的内容异步传播到缓存中,且仍然保证一致性。
小测验
我们时常觉得自己已经非常了解内存一致性和缓存一致性了,以下的一些判断题可以帮助读者判断是否充分了解了相关的概念。
在一个保持顺序一致性的系统中,一个核心必须按程序顺序发出一致性请求。
内存一致性模型规定了缓存一致性请求的合法顺序。
为了执行一个原子的read-modify-write(如test-and-set),一个核必须始终与其他核进行通信。
在一个有多线程核心的TSO系统中,线程可以绕过write buffer的值,而不用管是哪个线程写入的值。
相对于高级语言的一致性模型(如Java),程序员编写适当的同步代码,不需要考虑架构的内存一致性模型。
在MSI总线嗅探协议中,一个缓存行只能处于三种一致性状态中的一种。
总线嗅探缓存一致性协议要求内核必须在总线上通信。
GPU不支持硬件缓存一致性,因此无法实现内存一致性模型。
基本系统模型
我们考虑的是具有多个处理器内核的系统,所有处理器都可以对共享内存进行load和store,且每个内核都有自己的私有数据缓存,可能还有一个共享的最后一级缓存(LLC)。不过我们介绍缓存时,都指私有数据缓存而非LLC。
缓存不一致的情况
上图说明了一种缓存不一致的情况,C1和C2都缓存了A的值,假设A的初始值为42,C1往缓存中写入A=43,但并没有同步到C2,因此C2陷入了无限循环。
缓存一致性接口
处理器通过一致性接口(如上图)与一致性协议进行交互,包括:
read-request:接收一个内存地址并返回一个值。
write-request:接收一个内存地址和一个将要写入的值,并返回一个确认信号。
可以按照缓存一致性接口的性质将缓存一致性协议分为两类:
内存一致性无关的缓存一致性:一次写入在返回之前就对其他所有内核可见,由于内存写入是同步传播的,这类协议提供了一个与原子内存系统相同的接口。这种协议可以很好地将缓存完全抽象化,处理器流水线只需执行内存一致性模型规定的顺序即可。
内存一致性相关的缓存一致性:内存写入是异步传播的,因此写入可以在被所有处理器看到之前返回,允许处理器观察非最新的值,但仍然需要遵守内存一致性规定的顺序。
(内存一致性无关的)缓存一致性不变性
我们通过单写多读(single-writer-multiple-reader, SWMR)不变性来定义一致性,如下图所示,同一时刻要么有一个核心在写,要么有一个或多个核心在读,两者不会同时发生。
与此同时,我们需要保证一个内存位置在一个时间片开始时的值与该内存位置在其上一个时间片结束时的值相同,称为data-value不变性。