一、缓存一致性
受功耗等因素的限制,单处理器的主频无法无限提高,促使处理器向多核架构发展。另一方面,多级缓存可以有效节省带宽,提升数据访问效率。多核处理器架构和多级缓存存储体系的发展催生了缓存一致性问题。缓存一致性问题的出现,主要是由于多处理器的共享存储(如主存)中保存着全局状态,而不同的处理器又各自拥有本地缓存,处理器对本地缓存的操作没有及时传播到其他处理器的本地缓存或共享存储,从而导致本地缓存中的数据可能与共享存储中同一地址对应的数据出现不一致。下表展示了一个缓存不一致的典型状况
[1]
:
在上表中,处理器A对位置X采取直写操作,主存被更新但处理器B的本地缓存没有被同步更新,从而造成了不一致。
如果在一个存储系统中处理器在任何时候读取存储器都能返回最新的写入值,那么这个存储系统是一致的。从这一定义看,缓存一致性牵涉到两个方面[1]:一致性(coherency)和连贯性(consistency)。它们的含义是:
缓存一致性需要从硬件和软件两个方面来保证,其中硬件主要保证一致性,而软件主要保证连贯性,我们在以下两个小节中分别讨论。
二、缓存一致性:处理器的视角
本小节简要讨论硬件如何维护缓存一致性。多处理器系统中,硬件设计必须保证处理器能读到其他处理器所写的最新值。这就要求多处理器系统满足以下三个要求[1]:
处理器P对位置X进行先写后读操作,在写和读之间没有其他处理器写位置X,则P应读到它上一次写操作写入X的值;
处理器P对位置X进行写操作,然后处理器Q对位置X进行读操作,如果在写和读之间没有其他处理器对位置X进行写操作,且读与写间隔足够长的时间,则Q应读取到P上次写操作写入X的值;
在所有处理器看来,任意两个处理器对相同位置的写入操作的顺序是相同的,这被称为写入操作的串行化。
处理器使用缓存一致性协议来保证多处理器系统满足以上三个要求。缓存一致性协议主要有目录式和监听式两种实现方法。它们的基本思路都是维护缓存中数据块的状态,从而当处理器访问某数据块时可以知道该数据块是最新的还是失效的以及哪里有最新的数据块,从而能获取写入其访问的存储地址的最新值。目录式一致性协议用目录来保存缓存中的数据块状态,而监听协议用总线发送数据块状态。
三、缓存一致性:程序员的视角
仅仅保持一致性并不能保证一定能读取到最新值,这是因为写入操作和写入结果的传播有一定延迟。这就是说如果一个读操作在一个写操作之后很短的一段时间之内发生,那么该读操作可能读不到该写操作写入的值。这就需要系统保证在上文中提到的连贯性,这一保证主要是由程序员编写的程序满足存储一致性模型来完成的。存储一致性模型是软件和存储系统之间对访存行为的一种约定,当软件的访存行为符合存储一致性模型时,可以得到预期的正确访存结果,否则可能无法得到预期的正确访存结果。常见的访存一致性模型有严格一致性模型(Strict Consistency)、顺序一致性模型(SequentialConsistency)、因果一致性模型(Causal Consistency)、处理器一致性模型(Processor Consistency)、弱一致性模型(WeakConsistency)、释放一致性模型(Release Consistency)和单项一致性模型(Entry Consistency)。不同的存储一致性模型对处理器访存的顺序和访存结果的传播有不同的要求,我们主要介绍顺序一致性模型、处理器一致性模型、弱一致性模型和释放一致性模型,它们逐步放松了对访存顺序的要求。
顺序一致性模型[1]要求程序每次执行的结果都是一样的,就像每个处理器按顺序完成访存操作,不同处理器之间的访存操作可以互相交错,但不应该因为延迟等问题导致访存顺序不确定。一种顺序一致性的实现方法是当写入一个位置X时,使X在其他缓存中的副本都失效,只有当写入位置成功更新且副本全部失效时该写入操作才算完成。
处理器一致性模型[3]要求同一处理器发射的所有写操作以相同的顺序相对于系统中的能观察到这些操作的所有处理器执行完毕,而不同处理器发射的写操作可以以不同的顺序相对于系统中能观察到这些操作的处理器执行完成。处理器一致性模型满足:
在弱一致性模型[2]中引入同步变量,同步变量可以用于不同进程间执行过程的同步,从而控制访存顺序。同步[5]一般指的是在两个或多个数据库、文件、模块、线程或进程之间用来保持数据内容一致性的机制。弱一致性模型满足如下三个要求:
释放一致性模型[2]提供了两类同步操作:Acquire和Release。某进程将要进入临界区时执行Acquire操作,退出临界区时执行Release操作。临界区[4]指的是一个访问共用资源(例如:共用设备或是共用存储器)的程序片段,而这些共用资源又具有无法同时被多个线程或进程访问的特性。Acquire操作和Release操作保证在同一时间只有一个进程进入临界区,即当一个进程Acquire操作成功但没有Release操作之前,另一个进程对该临界区的Acquire操作不会成功从而进行等待。
在任一普通访存操作被允许执行之前,所有在同一进程中先于这一访存操作的 Acquire 操作都己完成;
在任一Release 操作被允许执行之前,所有在同一进程中先于这一Release 操作的读操作和写操作都已完成;
Acquire操作和Release操作的顺序必须满足处理器一致性要求。
也可以不用临界区而用栅栏(Barrier)同步来实现释放一致性协议。栅栏是一种同步机制,它要求所有的进程全都到达程序的某一同步点之后,各个进程才能继续往下执行。
相对于顺序一致性,处理器一致性模型、弱一致性模型和释放一致性模型放松了对读写操作顺序的要求。处理器一致性模型放松了对读操作和写操作之间顺序的要求,但保持了写操作之间的顺序。而弱一致性模型和释放一致性模型则通过同步操作将排序的权利交给了程序员,进一步放松了对访存操作的顺序要求。释放一致性通过将同步操作分解为Acquire操作和Release操作进一步增加了编程的灵活性。
四、结语
本期我们介绍了缓存一致性的基础知识,下一期中我们分析一下ARMv8-A架构中的原子性和访存顺序。
【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
评论(0)