研究!rsc公司

关于编程的想法和链接,通过

RSS(RSS)

硬件内存型号
(内存模型,第1部分)
发布于2021年6月29日,星期二。PDF格式

引言:童话,结局

很久以前,当每个人都编写单线程程序时,让程序运行得更快的最有效方法之一是坐下来什么也不做。下一代硬件和下一代编译器的优化会使程序像以前一样运行,只是速度更快。在这个童话时代,对于优化是否有效,有一个简单的测试:如果程序员看不出区别(除了加速)在有效程序的未优化执行和优化执行之间,那么优化是有效的。那就是,有效的优化不会改变有效程序的行为。

几年前的一天,硬件工程师的魔咒使单个处理器越来越快停止工作。作为回应,他们发现了一种新的魔法创建具有越来越多处理器的计算机,操作系统暴露了这种硬件并行性线程抽象中的程序员。这种新的魔法多处理器以以下形式提供操作系统线程对硬件工程师来说工作得更好,但它给语言设计者、编译器编写者和程序员带来了重大问题。

许多不可见的硬件和编译器优化(因此有效)在单线程程序中在多线程程序中产生可见的更改。如果有效的优化没有改变有效程序的行为,那么,必须将这些优化或现有程序声明为无效。我们该怎么决定?

下面是一个类似C语言的简单示例程序。在这个程序和我们要考虑的所有程序中,所有变量最初都设置为零。

//螺纹1//螺纹2x=1;while(done==0){/*循环*/}完成=1;打印(x);

如果线程1和线程2各自在其自己的专用处理器上运行,都运行到完成,这个程序可以打印0吗?

视情况而定。这取决于硬件,也取决于编译器。直接将线对线转换为程序集在x86多处理器上运行将始终打印1。但在ARM或POWER上直接进行汇编的线对线转换多处理器可以打印0。此外,无论底层硬件是什么,标准编译器优化可以使该程序打印0或进入无限循环。

“视情况而定”并不是一个圆满的结局。程序员需要清楚地回答程序是否会继续使用新硬件和新编译器。硬件设计师和编译器开发人员需要清楚地回答硬件和编译代码的精确程度允许在执行给定程序时执行。因为这里的主要问题是可见性和一致性存储在内存中的数据的更改,该契约称为内存一致性模型或者只是存储器模型.

最初,内存模型的目标是定义什么硬件保证程序员编写汇编代码。在该设置中,不涉及编译器。25年前,人们开始尝试编写记忆模型定义Java或C之类的高级编程语言++保证程序员用该语言编写代码。在模型中包含编译器使得定义一个合理的模型要复杂得多。

这是一对柱子中的第一根关于硬件内存模型和编程语言存储模型。我写这些帖子的目的是为讨论潜力我们可能想在Go的内存模型中进行的更改.但为了了解Go在哪里以及我们可能想去哪里,首先,我们必须了解其他硬件内存模型的位置语言记忆模型是当今不稳定的发展道路他们想去那里。

同样,这篇文章是关于硬件的。假设我们正在为多处理器计算机编写汇编语言。程序员需要从计算机硬件上得到什么保证为了编写正确的程序?计算机科学家一直在寻找这个问题的好答案四十多年了。

顺序一致性

莱斯利·兰波特1979年的论文“如何制作多处理器计算机正确执行多进程程序“介绍了顺序一致性的概念:

设计和证明正确性的惯用方法对于这种计算机的多进程算法,假设满足以下条件:任何执行的结果与执行所有处理器的操作相同按照一定的顺序,以及每个个体的操作处理器按其程序指定的顺序出现在这个序列中。满足此条件的多处理器将被调用地始终如一.

今天,我们不仅讨论计算机硬件,还讨论编程语言保证顺序一致性,当只有可能的执行对应于某种线程交错的程序将操作转换为顺序执行。序列一致性通常被认为是理想模型,这是程序员最自然的工作方式。它允许您假定程序按页面上显示的顺序执行,单个线程的执行只是交错进行按照一定的顺序,但没有重新安排。

人们可能会合理地质疑序列一致性应该成为理想的模特,但这超出了本文的范围。我只会注意到,考虑到所有可能的线程交织仍然存在,今天和1979年一样,“设计和证明多进程算法正确性的惯用方法。”在其间的四十年里,没有什么能取代它。

早些时候我问这个程序是否可以打印0:

//螺纹1//螺纹2x=1;while(done==0){/*循环*/}完成=1;打印(x);

为了使程序更容易分析,让我们删除循环和打印并询问读取共享变量的可能结果:

石蕊测试:信息传递
这个程序能看到吗第1个 = 1,第2页 = 0?

//螺纹1//螺纹2x=1 r1=yy=1 r2=x

我们假设每个示例都以所有共享变量设置为零开始。因为我们正试图确定允许硬件做什么,我们假设每个线程都在自己的专用处理器上执行并且没有编译器对线程中发生的事情进行重新排序:清单中的指令是处理器执行的指令。姓名第页N个表示线程本地寄存器而不是共享变量,我们询问是否可以对线程寄存器进行特定设置在执行结束时。

这种关于执行结果的问题示例程序称为石蕊试验.因为它有一个二元答案-这个结果可能吗-石蕊测试给了我们一个区分内存模型的明确方法:如果一个模型允许特定执行而另一个不允许,这两种模式明显不同。不幸的是,我们稍后会看到,特定模型对特定石蕊测试的回答往往令人惊讶。

如果此石蕊测试的执行顺序一致,则只有六种可能的交错:

由于没有交错以第1个 = 1,第2页 = 0,该结果不允许。也就是说,在顺序一致的硬件上,石蕊测试的答案可以在这个程序中看到第1个 = 1,第2页 = 0?—.

序列一致性的一个好的心理模型是想象所有处理器直接连接到同一共享内存,可以为读或写请求提供服务每次从一个线程。不涉及缓存,因此每次处理器需要从中读取或写入时内存中,该请求将发送到共享内存。一次性使用的共享内存对所有内存访问的执行:顺序一致性。

(本文中的三个内存模型硬件图改编自马兰杰 ., “ARM和POWER松弛内存模型教程介绍.”)

此图是一个模型对于顺序一致的机器,不是唯一的建造方法。实际上,可以构建一个顺序一致的机器使用多个共享内存模块和缓存来帮助预测内存获取的结果,但顺序一致意味着那台机器的性能必须与这种型号的机器区分开来。如果我们只是试图理解顺序一致的执行手段,我们可以忽略所有这些可能的实现复杂性想想这个模型。

不幸的是,作为程序员,放弃严格的顺序一致性可以让硬件更快地执行程序,因此,所有现代硬件都在不同程度上偏离了顺序一致性。准确定义特定硬件的偏差结果是相当困难的。这篇文章使用了两种内存模型作为两个示例在当今广泛使用的硬件中:x86,以及ARM和POWER处理器系列。

x86总商店订单(x86-TSO)

现代x86系统的内存模型与此对应硬件图:

所有处理器仍连接到单个共享内存,但每个处理器队列在本地写入队列中向该内存写入数据。处理器继续执行新指令而写操作会进入共享内存。在一个处理器上读取的内存会参考本地写入队列在查询主存储器之前,但是它看不到其他处理器上的写入队列。其结果是,处理器可以在其他处理器之前看到自己的写入。但是,这一点非常重要,所有处理器都同意写入(存储)到达共享内存的(总计)顺序,为模型命名:总存储订单或TSO。当写操作到达共享内存时,以后在任何处理器上读取时都会看到它并使用该值(直到它被稍后的写入覆盖,或者可能被缓冲的从另一个处理器写入)。

写入队列是一个标准的先进先出队列:内存写入以相同的顺序应用于共享内存它们是由处理器执行的。由于写入队列保留了写入顺序,因为其他处理器会看到对共享内存的写入马上,信息传递石蕊测试我们之前考虑的结果与之前相同:第1个 = 1,第2页 = 0仍然不可能。

石蕊测试:信息传递
这个程序能看到吗第1个 = 1,第2页 = 0?

//螺纹1//螺纹2x=1 r1=yy=1 r2=x

在顺序一致的硬件上:否。
在x86(或其他TSO)上:否。

写入队列保证线程1写入x个记忆之前,以及关于内存写入顺序的系统范围协议(总存储订单)确保线程2学习x个的新值的新值。因此,不可能第1个 = 看到新的没有第2页 = x个也看到了新的x个.商店订单在这里至关重要:线程1写入x个之前,因此线程2不能看到写入在写入之前x个.

在这种情况下,顺序一致性和TSO模型是一致的,但他们不同意其他石蕊测试的结果。例如,这是区分这两种模型的常见示例:

Litmus测试:写入队列(也称为存储缓冲区)
这个程序能看到吗第1个 = 0,第2页 = 0?

//螺纹1//螺纹2x=1 y=1r1=y r2=x

在顺序一致的硬件上:没有。
在x86(或其他TSO)上:对!

在任何顺序一致的执行中x个 = 1 = 1必须先发生,然后另一个线程中的读取必须观察它,所以第1个 = 0,第2页 = 0是不可能的。但在TSO系统上,可能会发生线程1和线程2都将其写入排队的情况然后在写入到内存之前从内存中读取,这样两个读数都会看到零。

这个示例看起来可能是人为的,但在众所周知的同步算法中确实会使用两个同步变量,例如德克尔算法彼得森算法,以及临时方案。如果一个线程没有看到另一个线程的所有写操作,它们就会中断。

要修复依赖更强内存顺序的算法,非连续一致硬件提供称为内存屏障(或围栏)的显式指令可以用来控制订单。我们可以添加内存屏障以确保每个线程在开始读取之前刷新其上一次对内存的写入:

//螺纹1//螺纹2x=1 y=1屏障屏障r1=y r2=x

随着屏障的增加,1号机组 = 0,第2页 = 0也是不可能的,然后德克尔或彼得森的算法就会正常工作。障碍有很多种;细节因系统而异并且超出了本文的范围。关键是障碍的存在给了程序员或语言实现者在关键时刻强制顺序一致行为的方法在程序中。

最后一个例子,解释为什么这个模型被称为总店铺订单。在该模型中,存在本地写入队列,但读取路径上没有缓存。一旦写入到达主存,所有处理器不仅同意值是存在的,但也就它相对于写入的到达时间达成一致来自其他处理器。考虑一下这个石蕊试纸:

石蕊测试:独立写作的独立阅读(IRIW)
这个程序能看到吗第1个 = 1,第2页 = 0,第3轮 = 1,r4型 = 0?
(Can螺纹3和4参见x个改变不同的顺序?)

//螺纹1//螺纹2//螺纹3//螺纹4x=1 y=1 r1=x r3=yr2=y r4=x

在顺序一致的硬件上:否。
在x86(或其他TSO)上:否。

如果线程3看到x个之前的更改,线程4可以看到吗之前的更改x个?对于x86和其他TSO机器,答案是否定的:有一个总订单覆盖所有存储(写入)到主存储器,所有处理器都同意该顺序,每个处理器在到达主内存之前都知道自己的写操作,这可能会带来麻烦。

x86-TSO之路

x86 TSO模型看起来相当干净,但那里的道路充满了障碍和错误的转弯。20世纪90年代,第一台x86多处理器的可用手册中说几乎没有关于硬件所提供的内存模型。

作为问题的一个例子,Plan 9是第一个真正的多处理器操作系统之一(没有全局内核锁)在x86上运行。1997年,在连接到多处理器奔腾Pro的过程中,开发人员意外的行为这归结为写队列石蕊测试。一段微妙的同步代码假设第1个 = 0,第2页 = 0这是不可能的,但它正在发生。更糟糕的是,英特尔手册对内存模型的详细信息含糊不清。

针对一份邮件列表中的建议,“最好保持保守”使用锁,而不是相信硬件设计师会做我们期望的事情,”计划9开发商之一很好地解释了问题:

我当然同意。我们将遇到更宽松的订单在多处理器中。问题是,硬件是什么设计师认为保守吗?强制联锁锁定部分的开头和结尾似乎都是对我来说相当保守,但我显然没有想象力够了。专业手册详细描述了缓存以及使它们保持一致但似乎不在乎的东西详细说明执行或读取顺序事实是,我们无法知道自己是否保守够了。

在讨论中,Intel的一位架构师给出了一个非正式的记忆模型的解释,从理论上指出即使是多处理器486和奔腾系统也可以产生这个第1个 = 0,第2页 = 0结果,奔腾Pro只是有了更大的管道和写队列,暴露了行为更频繁。

这位英特尔架构师还写道:

粗略地说,这意味着事件的顺序从系统中的任何一个处理器,如其他处理器所观察到的,总是一样的。然而,允许不同的观察员对两个或两个以上事件的交错存在分歧处理器。

未来的英特尔处理器将实现相同的内存订购模型。

声称“允许不同的观察者对两个或两个以上事件的交错存在分歧处理器”是指IRIW石蕊测试的答案可以在x86上回答“是”,即使在上一节中我们看到x86回答“不”怎么会这样?

答案似乎是英特尔处理器实际上从来没有对石蕊测试的回答是“是”,但当时英特尔的架构师不愿为未来的处理器做出任何保证。架构(architecture)手册中几乎没有文字几乎没有任何保证,因此很难进行编程。

9号计划的讨论并不是一个孤立的事件。Linux内核开发人员花费了超过100条消息在他们的邮件列表上1999年11月下旬开始在类似的混乱中英特尔处理器提供的保证。

为了应对越来越多的人遇到这些困难在接下来的十年里,英特尔的一组架构师承担了写下来的任务对当前和未来处理器的处理器行为都提供了有用的保证。第一个结果是Intel 64体系结构内存订购白皮书”,2007年8月出版,其目的是“为软件作者提供对不同的内存访问指令序列可能产生的结果。”AMD在当年晚些时候的AMD64架构(Architecture)程序员手册3.14版.这些描述基于一个名为“总锁顺序+因果一致性”(TLO+CC),故意弱于TSO。在公开会谈中,英特尔架构师表示,TLO+CC“和要求的一样强壮,但并不强壮。”特别是,该模型保留了以下权利:x86处理器在IRIW石蕊测试中回答“是”。不幸的是,记忆障碍的定义是不够强壮重建顺序一致的记忆语义,即使每次指令后都有障碍。更糟糕的是,研究人员观察到实际的Intel x86硬件违反TLO+CC模型。例如:

石蕊试验:n6(Paul Loewenstein)
这个节目能以结尾吗第1个 = 1,第2页 = 0,x个 = 1?

//螺纹1//螺纹2x=1 y=1r1=x x=2r2=y

在顺序一致的硬件上:否。
在x86 TLO+CC模型(2007)上:否。
在实际的x86硬件上:对!
在x86 TSO型号上:对!(示例来自x86-TSO论文。)

2008年晚些时候对Intel和AMD规范的修订保证对IRIW案件“不”,并且强化记忆障碍但仍允许出现以下意外行为它们不可能出现在任何合理的硬件上。例如:

石蕊试验:n5
这个节目能以结尾吗第1个 = 2,第2页 = 1?

//螺纹1//螺纹2x=1 x=2r1=x r2=x

在顺序一致的硬件上:否。
关于x86规范(2008):对!
在实际的x86硬件上:没有。
在x86 TSO型号上:否。(x86 TSO论文中的示例。)

为了解决这些问题,欧文斯 .提出了x86-TSO模型,基于较早的SPARCv8 TSO模型.当时他们声称“据我们所知,x86-TSO是可靠的,足以编程并且大体上符合供应商的意图。”几个月后,英特尔和AMD发布了新的手册广泛采用这种模式。

似乎所有英特尔处理器从一开始就实现了x86-TSO,尽管英特尔花了十年时间才决定这么做。回想起来,很明显,英特尔和AMD的架构师都在苦苦挣扎以及如何编写一个内存模型为将来的处理器优化留出了空间为编译器编写者和汇编语言程序员提供有用的保证。“如要求般强大,但并不强大”是一种难以平衡的行为。

ARM/POWER松弛内存模型

现在让我们来看一个更轻松的记忆模型,ARM和POWER处理器上的一个。在实施层面,这两个系统在很多方面都不同,但保证内存一致性模型结果大致相似,比x86-TSO甚至x86-TLO+CC都弱。

ARM和POWER系统的概念模型是每个处理器读取和写入自己的完整内存副本,每个写操作都独立地传播到其他处理器,随着写操作的传播,允许重新排序。

这里没有总的商店订单。未描述,每个处理器也可以推迟读取直到它需要结果:读取可以延迟到稍后的写入之后。在这个放松的模型中,我们迄今为止看到的每一个石蕊测试的答案都是“是的,这确实可能发生。”

对于通过石蕊测试的原始消息,单处理器写操作的重新排序表示可能无法观察到线程1的写入按相同顺序由其他线程执行:

石蕊测试:信息传递
这个程序能看到吗第1个 = 1,第2页 = 0?

//螺纹1//螺纹2x=1 r1=yy=1 r2=x

在顺序一致的硬件上:否。
在x86(或其他TSO)上:否。
在ARM/POWER上:对!

在ARM/POWER模型中,我们可以认为线程1和线程2都具有它们自己独立的内存拷贝,写操作会传播在记忆之间以任何顺序。如果线程1的内存发送更新发送更新之前发送到线程2x个,如果线程2在这两次更新之间执行,它确实会看到结果第1个 = 1,第2页 = 0.

该结果表明ARM/POWER内存模型弱于TSO:它对硬件的要求更少。ARM/POWER模型仍然允许TSO进行各种重新排序:

石蕊测试:储存缓冲
这个程序能看到吗第1个 = 0,第2页 = 0?

//螺纹1//螺纹2x=1 y=1r1=y r2=x

在顺序一致的硬件上:否。
在x86(或其他TSO)上:对!
在ARM/POWER上:对!

在ARM/POWER上,写入x个可能会成为读取发生在相反的线程上。

这是石蕊测试,它表明了它的意义x86的总存储订单:

石蕊测试:独立写作的独立阅读(IRIW)
这个程序能看到吗1号机组 = 1,第2页 = 0,第3轮 = 1,r4型 = 0?
(Can螺纹3和4参见x个不同订单的变化?)

//螺纹1//螺纹2//螺纹3//螺纹4x=1 y=1 r1=x r3=yr2=y r4=x

在顺序一致的硬件上:否。
在x86(或其他TSO)上:否。
在ARM/POWER上:对!

在ARM/POWER上,不同的线程可以了解不同的写入按不同顺序排列。他们不一定会同意大约总共到达主内存的写入顺序,因此线程3可以看到x个之前的更改而线程4看到之前的更改x个.

另一个例子是,ARM/POWER系统具有内存读取(加载)的可见缓冲或重新排序,如石蕊试验所示:

石蕊测试:负载缓冲
这个程序能看到吗第1个 = 1,第2页 = 1?
(是否可以读取每个线程之后另一个线程写了吗?)

//螺纹1//螺纹2r1=x r2=yy=1 x=1

在顺序一致的硬件上:否。
在x86(或其他TSO)上:否。
在ARM/POWER上:对!

任何顺序一致的交织都必须从开始任一线程1第1个 = x个或螺纹2第2页 = .读数必须为零,从而得出结果第1个 = 1,第2页 = 1不可能的。然而,在ARM/POWER内存模型中,处理器允许将读取延迟到指令流中稍后的写入之后,以便 = 1x个 = 1执行之前两人读着。

尽管ARM和POWER内存模型都允许这种结果,马兰杰 .报告(2012年)能够经验性地重现仅在ARM系统上,从不在POWER上。在这里,模型与现实之间的差异发挥了作用,正如我们在研究Intel x86时所做的那样:硬件实现了比技术保证更强大的模型鼓励依赖更强的行为也就是说,未来较弱的硬件将破坏程序,是否有效。

与TSO系统一样,ARM和POWER也有我们可以设置的障碍插入上述示例以强制顺序一致行为。但显而易见的问题是,没有障碍的ARM/POWER是否完全排除了任何行为。任何石蕊试纸的答案都会是“不,那不可能发生?”当我们关注单个内存位置时,它可以。

以下是对ARM和POWER上也不会发生的事情的试金石测试:

石蕊试验:一致性
这个程序能看到吗第1个 = 1,第2页 = 2,第3轮 = 2,r4型 = 1?
(螺纹3可参见x个 = 1之前x个 = 2而线程4则相反?)

//螺纹1//螺纹2//螺纹3//螺纹4x=1 x=2 r1=x r3=xr2=x r4=x

在顺序一致的硬件上:否。
在x86(或其他TSO)上:否。
在ARM/POWER上:否。

这个石蕊试纸和前一个一样,但现在两个线程都在写入单个变量x个而不是两个不同的变量x个.线程1和2将冲突的值1和2写入x个,而线程3和线程4均为x个两次。如果线程3看到x个 = 1被覆盖x个 = 2,线程4能看到相反的情况吗?

答案是否定的,即使是在ARM/POWER上:系统中的线程必须就总订单达成一致用于写入单个内存位置。也就是说,线程必须同意哪些写操作会覆盖其他写操作。此属性称为一致性.如果没有相干特性,处理器要么不同意内存的最终结果或者从一个值报告内存位置翻转到另一个,再回到第一个。对这样的系统进行编程将非常困难。

我故意省略了ARM和POWER弱内存模型中的许多细节。有关更多详细信息,请参阅彼得·苏厄尔关于这个主题的论文.此外,ARMv8强化记忆模型通过使其成为“多拷贝原子”但我不想在这里解释这到底意味着什么。

有两个要点需要注意。首先,这里有令人难以置信的微妙之处,十多年学术研究的主题由非常执着、非常聪明的人。我自己并没有声称能完全理解。我们不应该希望向普通程序员解释这一点,在调试普通程序时,我们不希望弄清这一点。第二,允许和观察之间的差距会给未来带来不幸的惊喜。如果当前硬件没有表现出所有允许的行为,特别是当一开始很难解释什么是允许的-然后不可避免地将编写偶然依赖于更受限制的行为的程序实际硬件。如果新芯片的行为受到较少限制硬件在技术上允许中断程序内存模型-也就是说,从技术上讲,这个错误是你的错-这没有什么安慰。这不是编写程序的方法。

弱排序和无数据面序列一致性

现在我希望你相信硬件细节是复杂而微妙的,不是你想解决的问题每次你写程序的时候。相反,它将有助于识别表单的快捷方式“如果你遵循这些简单的规则,你的程序只会产生结果就像是通过一些顺序一致的交织。”(我们仍在谈论硬件,所以我们仍在讨论关于交错单个汇编指令。)

Sarita Adve和Mark Hill正是提出了这种方法在他们1990年的论文中”弱有序——一个新的定义”. 他们将“弱序”定义如下。

让同步模型是一组约束指定如何以及何时进行同步的内存访问。

硬件相对于同步模型是弱序的如果且仅当它看起来与所有软件顺序一致符合同步模型。

尽管他们的论文是关于捕捉当时的硬件设计(非x86、ARM和POWER),将讨论提升到具体设计之上的想法,保持报纸今天的相关性。

我之前说过“有效的优化不会改变有效程序的行为。”这些规则定义了有效的含义,然后任何硬件优化都必须保持这些程序正常运行顺序一致的机器。当然,有趣的细节是规则本身,定义程序有效含义的约束。

Adve和Hill提出了一个同步模型,他们称之为无数据通道(DRF).此模型假设硬件具有内存同步操作独立于普通内存的读写。普通内存的读取和写入可以在同步操作,但不能在它们之间移动。(也就是说,同步操作也是重新排序的障碍。)程序被称为无数据追踪如果,对于所有理想的顺序一致执行,任意两个普通内存访问同一位置来自不同线程的都是read或else由同步操作强制分隔一个发生在另一个之前。

让我们看一些摘自阿芙和希尔论文的例子(重新绘制以供演示)。下面是执行变量写入的单个线程x个然后读取相同的变量。

垂直箭头标记单个线程内的执行顺序:先写,然后读。这个程序中没有竞争,因为一切都在一个线程中。

相反,在这个双线程程序中存在竞争:

在这里,线程2在不与线程1协调的情况下写入x。线程2的写入比赛同时使用写线程1和读线程1。如果线程2正在读取x而不是写入它,该程序在写入线程1之间只有一个竞争和读入线程2。每个竞争都至少涉及一次写入:两次不协调的读取不会相互竞争。

为了避免竞争,我们必须添加同步操作,这将强制不同线程上操作之间的顺序共享同步变量。如果同步S(a)(在变量a上同步,用虚线箭头标记)强制线程2在线程1完成后进行写入,比赛被淘汰:

现在,线程2的写操作不能与线程1的操作同时发生。

如果线程2只是在读取,我们只需要与线程1的写入同步。两次读取仍可以同时进行:

即使使用中间线程,也可以按同步序列对线程进行排序。此程序没有种族:

另一方面,同步变量的使用本身并不消除种族:可能会错误使用种族。这个节目确实有一场比赛:

线程2的读取与其他线程中的写入正确同步-这肯定会在两个线程之后发生-但这两个写操作本身并不同步。这个程序是无数据通道。

Adve和Hill将弱订单描述为“软件和硬件之间的合同”具体来说,如果软件避免了数据竞争,那么硬件就好像是这样顺序一致,这比我们检查的模型更容易推理在前面的章节中。但硬件如何满足合同的终止?

Adve和Hill给出了硬件“被DRF弱排序”的证明这意味着它执行无数据通道的程序,就像按顺序一致的顺序执行一样,只要满足一组特定的最低要求。我不打算详谈细节,但重点是是在Adve and Hill报纸之后,硬件设计师有一本食谱,食谱上有证据支持:做这些事情,你可以断言您的硬件将显示顺序一致到无数据通道程序。事实上,最宽松的硬件确实是这样做的,并且一直在这样做,假设同步操作的适当实现。Adve和Hill最初关注VAX,但当然x86、ARM和POWER也可以满足这些限制。这种系统保证无数据竞赛程序的想法序列一致性的出现常常被缩写DRF-SC公司.

DRF-SC标志着硬件内存模型的一个转折点,为硬件设计师和软件作者,至少是那些用汇编语言编写软件的人。我们将在下一篇文章中看到,高级编程语言的内存模型问题没有那么整洁的答案。

本系列的下一篇文章是关于编程语言存储模型.

致谢

这一系列帖子从与以及我很幸运能在谷歌共事的一长串工程师的反馈。我感谢他们。我对任何错误或不受欢迎的意见承担全部责任。