首页 > 其他分享 >第五章:Relaxed Memory Consistency

第五章:Relaxed Memory Consistency

时间:2024-04-30 16:17:00浏览次数:25  
标签:load FENCE XC Relaxed Consistency 内存 Memory 一致性 store

chapter5:宽松的内存一致性

之前所讨论的SC和TSO需要对所使访存顺序符合程序顺序,称为强一致性模型。而目的在于只保留程序员真正需要的顺序的弱一致性模型,可以允许更多的硬件或软件优化(编译器或运行时)减少排序约束,进一步提升性能。

1、为什么需要宽松内存一致性


程序员总是期望以下执行顺序

  • S1 -> S3 -> L1 loads SET -> L2
  • S2 -> S3 -> L1 loads SET -> L3

除此之外,TSO和SC还会保留S1和S2、L2和L3之间的顺序。

上图描述了一个更普遍的情况,即两个critical section(以下简称CS)使用同一个锁进行交接,其正确性由以下顺序进行保证:

  • All L1i, All S1j -> R1 -> A2 -> All L2i, All S2j

其正确性并不取决于CS内的load和store的顺序(除非load和store的地址相同),只需要保证先执行CS1再执行CS2。在这种情况下,load和store可以按任意顺序执行,或许可以通过放松load和store之间的顺序来获取更高的性能。

一个宽松的内存模型,可以对任何内存操作进行重排,并由FENCE指令进行必要的排序。这种模型需要程序员手动确定哪些操作需要排序可能比较麻烦,但也可以进行很多优化以提高性能。

常见的优化方法

不基于FIFO的合并式Write Buffer

在TSO中我们要求write buffer必须是基于FIFO的,但一个更优化的设计是使用不基于FIFO的write buffer,且允许同一地址或相邻地址的多个store请求合并为一个store。

对乱序执行的core支持更简单

在强一致性模型的系统中,一个内核可能在指令提交之前推测性地执行不按程序顺序的load,如MIPS R10000,但这样需要额外的检查流程,如MIPS R10000。相比之下,在宽松一致性模型中,乱序load符合模型要求,不需要额外的检查。

耦合的内存一致性与缓存一致性

宽松的一致性模型允许两个线程逻辑上共享一个核的write buffer等行为,容易形成一些核心load新值而另一些核心load旧值的情况出现,这短暂地打破了缓存一致性需要的“SWMR”不变量。因而需要特殊的、与一致性模型紧耦合的缓存一致性协议配合,这通常能够增强系统性能,但同时也带来相当大的验证复杂性。

2、弱一致性模型示例(Relaxed Consistency model,XC)

XC基本思想

XC提供了一个FENCE指令,在没有FENCE指令的情况下,load和store都可以是乱序的。FENCE指令不指定地址,同一个核的FENCE指令之间严格顺序,但FENCE不影响其他内核的内存指令顺序。

XC访存顺序保证以下程序顺序

  • Load -> FENCE
  • Store -> FENCE
  • FENCE -> FENCD
  • FENCE -> Load
  • FENCE -> Store

在操作相同地址时,采用TSO相同的规则

  • Load→Load to same address
  • Load→Store to same address
  • Store→Store to same address

对同一地址的顺序约束还是有必要的,比如Store -> Store规则可以避免出现先执行A=1再执行A=2但结果是A=1的情况,或者Load -> Load规则可以避免出现一开始A=0且有一个处理器写入A=1时,另一个处理器上第一次load A结果为1但是第二次load A结果为0的情况。

XC保证了load立即看到自己的store请求,类似TSO的write buffer bypassing,这样保证了单线程的顺序性。

XC中使用FENCE

XC形式化描述

所有内核都按如下规则将load、store和FENCE插入内存顺序<m:

  • 若L(a) <p FENCE,则L(a) <m FENCE
  • 若S(a) <p FENCE,则S(a) <m FENCE
  • 若FENCE <p FENCE,则FENCE <m FENCE
  • 若FENCE <p L(a),则FENCE <m L(a)
  • 若FENCE <p S(a),则FENCE <m S(a)

所有内核都将相同地址的load和store请求按如下顺序插入内存顺序<m:

  • 若L(a) <p L'(a),则L(a) <m L'(a)

  • 若L(a) <p S(a),则L(a) <m S(a)

  • 若SL(a) <p S'(a),则S(a) <m S'(a)

每一次load都从之前最后一次相同地址的store中获取值:

  • L(a)的值为MAX_<m

执行案例




3、XC实现

由reorder模块替换TSO中基于fifo的write buffer

  • 重排序单元(reorder unit)与core分开,loads、stores、FENCEs遵循程序顺序离开core并进入reorder unit的尾部。
  • reorder unit根据相关排序规则对消息进行排序并送至reorder unit的头部。
  • 当头部指令可以执行时((a)图中为被switch选中,(b)图中为L1缓存中的块有对应的权限)在头部执行load/store。

遵循以下规则

  • FENCE:FENCE的实现方法有很多,如1)按照SC模型排序,则FENCE看作no-ops;2)等待所有FENCE前的指令执行,全部执行完毕后再执行FENCE后的指令;3)更加激进的实现方式。但无论哪种实现都不应该重排序load→FENCE, store→FENCE, FENCE→ FENCE, FENCE→load, FENCE→store。
  • 对于同一地址的访存操作,reorder unit不能乱序 load→load, load→store, store→store.
  • load立即看到由于自身的store引发的更新。

实现原子指令

RMW的实现也取决于系统如何实现XC。在本节中,我们假设XC系统由乱序内核组成,每个内核通过一个不基于FIFO的合并式write buffer与内存系统相连。

一个简单方案是借用在TSO中讨论过的实现方式,在执行一个原子指令之前,清空write buffer,然后获得缓存块的读写权限(如M状态),然后进行load和store。但这种方案过于保守,牺牲了一部分性能。我们事实上不需要清空write buffer,因为XC允许RMW的load和store可以直接bypass之前的store

4、无数据争用程序的顺序一致性(Sequential Consistency For Data Race Free(DRF) Programs)

对于内存一致性模型来说同时具备SC模型的直观性和XC模型的高性能似乎是不可能的。但是对于无数据竞争程序而言是可以同时满足这两个目标的。数据竞争的概念是,当两个线程访问同一个内存位置,且至少有一个访问是store,且中间没有同步操作。通常数据竞争是编程错误导致的,许多程序员期望写无数据竞争的程序。

表5.7中,Core2没有进行同步操作,因而其load有可能和Core C1的store同时执行。由于XC模型允许Core1 S1,S2之间乱序,Core2 L1,L2之间乱序,则对应(r1, r2)会有四种输出结果:(0, 0), (0,NEW), (NEW, 0), (NEW, NEW)。

表5.8中,Core2进行了与Core1一样的acquire lock,这使得其critical section会完全先于(或后于)Core1的critical section。在这种情况下有两种可能输出结果:(r1, r2)=(0, 0), (NEW, NEW),尽管允许C1、C2都分别乱序执行S1、S2,L1、L2,但此时XC模型与SC模型输出结果是一致的。原因就是在C1执行乱序store时没有concurrent load被执行。

从上面的例子中我们可以看出,插入必要的FENCE之后,XC的结果与SC的结果是完全一样的。

  • 如果存在数据竞争,那么就会暴露XC对load和store的重排。
  • 如果不存在数据竞争,那么XC和SC执行结果没有区别。

为了对SC for DRF理解更深,需要引入以下定义:

  • synchronization:一种内存操作,包括lock acquire和lock release。一些内存操作被标记为“synchronization operations”,与之相对则是“data operations”

  • conflict:conflict有两种情况。

    • 第一种,来自不同核,或多线程处理器的不同线程的两个data operation Di和Dj,它们相同的内存地址,并且最少有一个operation是store。
    • 第二种,来自不同核,或多线程处理器的不同线程的两个synchronization操作Si和Sj访问了相同的内存地址,并且最少有一个operation是write(如spinlock的acquire和release)。
  • transive conflict:如果两个synchronization operation Si和Sj冲突,或者Si与Sk冲突,Sk <p Sk',Sk‘与Sj冲突,则Si与Sj构成transive conflict。

  • race:如果两个data operation产生conflict,并且它们的global memory顺序上没有一对来自各自处理器核(或线程)相干的transive conflict synchronization operation,那么这两个data operation构成竞争。换句话说,对于一对conflict的data operation Di <m Dj,当且仅当有一对相干的synchronization operation Si, Sj使得Di <m Si <m Sj < m Dj时,不会产生数据竞争。

  • 如果没有data operation竞争,那么一条SC的指令执行是data-race-free(DRF)的

  • 如果程序中所有SC的指令执行都是DRF的,那么这个程序是DRF的

  • 如果所有DRF程序的所有指令执行都是SC指令执行,那么称这个内存一致性模型支持“SC for DRF programs”

如上图所示,很难准确描述哪些内存操作可能发生数据竞争,因而必须保守地标记同步操作,插入FENCE。C2的“X=2”前后的FENCE当且仅当C1执行“X=1”的时候是被需要的,而判断出在C2执行“X=2”时C1是否执行“X=1”取决于C1之前的程序执行延时情况,这是不确定的。我们固然可以在所有不确定的情况下都插入FENCE,但是这会损伤性能。

5、一些宽松内存模型的概念

释放一致性(Release Consistency)

一个synchronization acquire只需要在其之后插入FENCE,一个synchronization release只需要在其之前插入FENCE即可。

如图5.4中,F11、F14、F21和F24可以省略。以C1的释放锁为例,F13不能省略,但F14可以,因为C1后续的内存操作在释放锁之前执行也是没有问题的。XC不允许有内存指令绕过FENCE,但RC允许这样的提前执行。事实上,RC提供了类似于FENCE的ACQUIRE和RELEASE指令,但只在一个方向上对内存访问进行排序,不同于在往前和王后两个方向进行排序的FENCE。

因果性和写入原子性

因果性(causality)在一致性模型中要求,如果一个核看到了一个写入结果并告诉了另一个核,那么另一个核也看到了这个结果。如表5.9中,如果r3=NEW,那么就保证了系统的causality。

写原子性(write atomicity)在内存一致性中要求,一个处理器核的store逻辑上立即被所有其它处理器核看到。同时,write atomicity允许store被自身处理器核先于其它处理器核看到。XC模型实际存在的 <m 内存顺序决定了其具备write atomicity的特性:在这之前,没有其它核看到了新值;在这之后,所有核都看到了新值。

标签:load,FENCE,XC,Relaxed,Consistency,内存,Memory,一致性,store
From: https://www.cnblogs.com/icwangpu/p/18168174

相关文章

  • openGauss 如何解决-out-of-memory-allocating-xxx-bytes-after-a-total-of-xxx-bytes
    如何解决"outofmemoryallocatingxxxbytesafteratotalofxxxbytes"报错问题如何解决编译过程中出现的“outofmemoryallocatingxxxbytesafteratotalofxxxbytes”报错。回答报错原因:脚本中的编译过程都添加了-sj参数,同时机器配置较低,内存不足,并发数太大导致......
  • 使用dmesg发现程序出现Out of memory的Case
    dmesg(displaymessage)是Linux和Unix系统中的一个命令行工具,用于显示内核与系统硬件交互的消息。运行此命令可能会显示一些关于系统错误或崩溃的信息:我使用了下面命令,dmesg-T|tail参数说明:-T:显示人类可读的时间戳,而不是默认的自系统启动以来的秒数。发现了下面情况:[Fri......
  • 第四章:Total Store Order and the x86 Memory Model
    chapter4:TSO于X86内存模型1、为什么需要TSO/x86处理器内核长期以来使用writebuffer来保存已提交的store指令,直到内存系统可以处理这些store请求。当store指令提交时,store请求进入writebuffer,而当需要写入的缓存行在内存系统中可以保证缓存一致性时,store请求就退出writebuffer......
  • Memory Layout of the C program
    reference:CompilationStepsandMemoryLayoutoftheCProgramStorageClassRAM明明断电会丢失数据,为什么初始化的全局变量存储在RAM?详细分析程序的存储TableofContentsMemoryLayoutoftheCProgramWhenyourunanyCprogram,itsexecutableimageis......
  • Compilation Steps and Memory Layout of the C program
    TableofContentsTableofContentsWhatarethefourstagesofthecompilationprocess?PreprocessingCompilationAssemblyLinkingWhatarethefourstagesofthecompilationprocess?NormallycompilingaCprogramisamulti-stageprocessandut......
  • 第三章:Memory Consistency Motivation and Sequential Consistency
    chapter3:内存为什么需要consistency和顺序Consistency本章深入研究内存consistency模型,这些模型为程序员和实现者定义了共享内存系统的行为。这些模型定义了行为正确性,以便程序员知道期望什么,实现者知道提供什么。1、共享内存行为存在的问题要了解为什么必须定义共享内存行......
  • Docker(二十)-Docker容器CPU、memory资源限制
    背景在使用docker运行容器时,默认的情况下,docker没有对容器进行硬件资源的限制,当一台主机上运行几百个容器,这些容器虽然互相隔离,但是底层却使用着相同的CPU、内存和磁盘资源。如果不对容器使用的资源进行限制,那么容器之间会互相影响,小的来说会导致容器资源使用不公平;大的来说,可......
  • Spark设置executor-memory后,executor显示的内存不符问题
    以该命令为例,我们设置一个executor并分配内存为2800m,可以看到ui上只给executor分配了1.5G的内存。同理,如果你设置了--executor-memory=1g,那么实际上只会有1048.8M的内存会被分配。spark-submit--masteryarn\--num-executors=1\--executor-memory=2800m\--classorg.apac......
  • Kernel panic - not syncing: Out of memory: system-wide panic_on_oom is enabled
    内存不足,导致Java 进程被杀掉。 [1534.300650]Kernelpanic-notsyncing:Outofmemory:system-widepanic_on_oomisenabled[1534.301803]CPU:5PID:2930Comm:javaKdump:loadedTainted:GO5.10.0-60.18.0.50.r1083_58.hce2.x86_64#1[153......
  • cenots7.6系统报“fork:Cannot allocate memory” 报错的解决方法(实操)
    今日早晨上班上报一台虚拟机无法ssh连接,想着大抵是关机了,又或是存储满了(经常遇到这样的事情,因为基本上都是做的厚置备,所以会导致分配容量大于实际容量)。打开后台查看报警事件,没有!预感到此事不大简单。。。。进入控制台,输入w好家伙,输出fork:Cannotallocatememory翻译一下:内......