一文读懂Memory consistency model (内存模型)

Memory consistency model又称Memory model (内存模型),定义了使用Shared memory(共享内存)执行多线程(Multithread)程序所允许的行为规范。Memory model定义了软硬件接口规范,以便程序员预料硬件会有什么行为,而硬件实现者知道可以使用什么样的优化,消除软硬件在配合上的歧义。

1.共享内存的问题

要了解为什么需要定义内存模型规范,我们先举个例子,如表1所示。系统中有两个cores在执行各自的代码,假设所有变量的初始值都是0,那么最终Core C2中寄存器r2的值应该为多少呢?

表1 寄存器r2的最终值为多少?

大多数程序员会期望Core C2的寄存器r2应该得到NEW值。然而,如今一些计算机系统中,最终寄存器r2的值可能是0。因为S1 store和S2 store访问不同的地址,硬件可能会对Core C1的S1 store和S2 store重排序,从而使得S2先于S1写到memory中。接下来,Core C2读取到Core C1的S2 store更新的flag值NEW,以为Core C1已经准备好了data值,就发起L2 load读取data返回给寄存器r2,而此时data值为0,也就导致最终寄存器r2为0。如下表2所示,程序的执行总顺序是S2->L1->L2->S1。

表2 程序的一种可能执行结果

对于相同地址的memory访问,硬件需要保证它们按照程序顺序(program order)执行,但硬件会对不同地址的memory访问进行重排序(Reorder),根据重排序的memory操作是load还是store,分为四种情况:

  • Store-store reorder:如果Core有一个非FIFO类型的write buffer,它允许store以不同于它们进入的顺序离开,那么两个store可能会被重新排序。比如第一个store在cache中miss,而第二个store hit cache,又或者第二个store与更老(older)的store合并(merge)到同一个write buffer的条目中。Store-store重排序对单线程执行没有影响。对多线程就会出现表1的现象。
  • Load-load reorder:Core的动态调度可以不按program order执行指令。如果表1中,Core C2可以乱序执行L1 load和L2 load。对于单线程执行,这种不同地址的重排序是安全的。但多线程中,Core C2的load重排序与Core C1的重排序store情况相同,如果memory按照L2->S1->S2->L1的顺序执行,那么寄存器r2将被赋值为0。
  • Load-store reorder:乱序执行的Core可以重排序来自同一线程不同地址的load和store指令。用年轻的(younger)的store重排序到较老(older)的load之前(load-store reorder)可能会导致不正确的行为,例如如果younger store是互斥锁(mutex)的解锁操作,那么被reorder的older load可能load到解锁之后的其它值。
  • Store-load reorder:如果将younger的load重排序到older的store之前,就如表3所示,可能会出现反直觉的结果r1和r2都是0。这种情况通常是系统中实现了FIFO类型的write buffer引起的。就比如Intel和AMD的x86系统。

表3 r1和r2可以同时为0吗

与单线程执行不同,多线程执行通常允许多个正确的行为,这种执行结果的不确定可能会让大家感觉困惑,但所有当今的多Core在默认情况下都是非确定性的,所有体系结构(architecture)都允许并发线程的多重交错执行。不过我们平时使用的软件会有适当的同步操作来将这些不确定性转成确定性的结果。因此,必须精确地定义memory model,减少这些不确定带来的影响。

2. Memory consistency model标准

2.1 4P原则

一个好的Memory consistency model应该具备以下4P原则:

  • Programmability:好的模型应该使编写多线程程序变得相对容易,而且对于大多数用户来说是直观的。
  • Performance:好的模型应该在合理的功耗、成本等条件下促进更高性能的实现,也应该给予实现者广泛的选择余地。
  • Portability: 好的模型应该被广泛采用,或者至少方向提供向后兼容或模型之间的转换能力。
  • Precision:好的模型应该是精确定义的,且用数学公式。自然语言描述太过模棱两可,通常会让受用者无法达到允许的极限。

2.2 Memory consistency model和cache coherency的联系和区别

之前的另一篇文章有详细的解释了cache coherency原理,需要的请翻看《一文读懂cache一致性原理》。Cache coherency和memory consistency很容易混淆,看似cache coherency定义了共享内存(Shared memory)的行为。但事实并非如此,从图1可以看到,coherency协议只是为core pipeline提供了一个内存系统(Memory system)的抽象,它本身不能决定共享内存的行为,反之,core pipeline也不能。

图1 consistency model

例如,如果core pipline以与program order相反的顺序将memory操作重排序并送给coherency协议,即使coherency协议正确地完成了它的工作,共享内存也会发生问题。总结来说:

  • Cache coherency不等于Memory consistency。Memory consistency是由core pipeline和cache coherency共同实现的,共同定义了共享内存的行为。
  • Memory consistency的实现可以把cache coherency当作是一个黑盒子。

3. 概念解释

为了方便大家的理解,本小节讲述了memory consistency中常见的几个概念,如图2。

  • Program order(程序顺序):是指程序内语句的顺序执行,这意味着语句将按照它们在代码中编写的顺序依次执行,除非遇到循环、条件或函数调用等控制流结构改变了执行流。
  • Memory order(内存顺序):是指系统中处理器(单个core或多个cores)的各个操作对内存进行访问的总顺序(total order)。
  • Single processor (core) sequential:是指任意指令的执行结果与按照程序指定的顺序执行的操作相同。
  • Multiprocessor sequentially consistent:是指任意执行的结果都是相同的,所有处理器的操作都按照某种内存顺序执行,并且每个处理器的操作按照其程序指定的顺序出现在内存顺序中。
  • Load:从memory中读取数据到寄存器。
  • Store:将寄存器数据写到memory中。
  • RMW:为了编写多线程代码,程序员需要能够同步不同线程,而这种同步通常需要执行成对的原子操作。这个功能是由原子执行的“read-modify-write” (RMW)指令提供的,例如:“test-and-set”, “fetch-and-increment”和 “compare-and-swap”。这些原子指令对于正确的同步至关重要,并用于实现spin-locks(自旋锁)和其它同步场景。比如spin-lock,程序员可以使用RMW来原子地读取锁的值是否为未锁定(等于0),并写入锁定的值(等于1)。
  • FENCE:执行FENCE可以确保program order在FENCE之前的memory操作先于比在FENCE之后的memory操作到达memory order上的。因此,FENCE也叫memory barriers。FENCE在SC模型中是不需要的,在TSO和relaxed模型中才需要的。不过TSO模型的程序员很少使用FENCE,因为TSO在大多数场景下不需要FENCE。但是FENCE对relaxed模型有重要作用。
  • Processor consistency:简称PC,表示一个Core的store操作按顺序达到其它Core,但不一定同时达到其它Core。TSO模型是PC的特殊情况,其中每个Core都可以立即看到自己的Store操作,但是当任何其它Core看到Store操作时,所有其它Core都可以看到它,这个属性称为write atomicity。

图2 memory system

关于load和store在program order和memory order上出现的位置可以用下图3方式来展示。中间垂直向下的箭头表示memory order (<m),而每个Core的向下箭头表示其program order (<p)。op1 <m op2意味着在memory order上,op1在op2之前。类似的op1 <p op2意味着在Core的program order中,op1在op2之前。在Sequential Consistency (SC,下文会详细介绍)中,memory order保留每个Core的program order。“保留”是指op1 <p op2意味着op1 <m op2。注释中的值(/* … */)为load或store的值。

图3 执行流表示

4. Memory consistency model分类

Memory consistency model主要可以分为Strong model和Relaxed model两大类,如下图4所示为常见的memory model。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

谷公子的藏经阁

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值