非临时存储(如movnti)是否按程序顺序到达内存?
因此,对于具有NVRAM的系统(如具有Intel 3D XPoint NVRAM的Intel Cascade Lake处理器),在发生崩溃时,缺乏重新排序可以确保写入同一缓存行的前缀占主导地位?
假设非临时存储的解析内存类型是WC(或WC+),我想你会问这个问题,答案大多不在英特尔和AMD处理器上。
对于英特尔处理器,"英特尔SDM V2"第11.3.1节中的某些语句指定了在至少有一个WC缓冲区的微体系结构上进行写操作的行为。
驱逐WC缓冲区的协议取决于实现并且不应该被软件依赖于系统存储器一致性。
这是一个一般性声明,指出WC驱逐的原因和为驱逐WC缓冲区而执行的事务取决于实现。但手册中的不同地方都有具体的说明。
类似地[在P6],对于以基于英特尔NetBurst微体系结构,一个完整的WC缓冲区始终作为单个突发事务传播,使用任何区块交易中的订单。
如果同一WC缓冲区中的所有字节都是有效的,这意味着自分配缓冲区以来,每个字节至少被写入一次,当缓冲区因任何原因被逐出时,缓冲区中整个缓存行都会使用单个事务被逐出。如果缓冲区的目标是内存控制器,它是CLX上持久性域中的第一个单元,则事务的所有字节都被持久化,或者没有字节。这意味着已写入该行的写入指令的程序顺序得到维护。这些特定写入和其他写入之间的顺序将在后面讨论。
";使用事务中的任何组块顺序";当事务的目标是内存控制器时,从软件的角度来看,该上下文中的部分并不重要,但对其他目标很重要。
英特尔已指定在所有微体系结构上对齐8字节的块大小。这种块大小仅适用于核心和非核心互连,但不超过实现其他协议的情况。但是,对于以IMC为目标的写入,在事务的粒度上可以保证持久原子性,事务可以包含1到64个字节(在所有现代英特尔和AMD处理器上,WC缓冲区的大小都是64个字节),这取决于缓冲区被逐出时同一WC缓冲区内有效字节的分布,也取决于确切的逐出协议。在英特尔处理器上,在WC缓冲区被完全逐出的情况下,事务保证包含所有64个有效字节。
AMD手册仅规定,完整的WC缓冲区驱逐可以作为单个事务执行。
以下引用指定了部分WC缓冲区移出(并非所有字节在缓冲区中都标记为有效)情况下的排序保证,以及不同WC缓冲区中写入之间的排序。它适用于英特尔和AMD处理器。
一旦WC缓冲区的驱逐开始,数据将受到其定义的弱排序语义。
该段的其余部分继续详细阐述。部分WC缓冲区可以使用一个或多个事务来收回,并且这些事务之间没有排序保证。一旦写入指令被提交到WC缓冲区,它在程序顺序中的位置就会完全丢失。如果这些事务的目标是IMC,则仅以单个事务的粒度提供持久原子性。这就是具有有效内存类型WC的写入可以在不保留早期WC写入的情况下持续的方式。如果不同的写入指令在同一WC缓冲区内部分重叠,则相对于同一WC缓冲器中的其他写入,写入指令可能会变得部分持久。WC缓冲区中跨越块边界的写操作在体系结构上不能保证是原子操作,除非缓冲区在组合写操作后(在英特尔处理器上)已完全满。
WC缓冲器可以按照不同于缓冲器分配顺序的顺序被逐出。围栏指令不能用于选择性地刷新WC缓冲区。然而,除了WC之外的任何类型的写入,其中存在重叠分配的WC缓冲区,导致该缓冲区尤其在执行写入之前被逐出。在WCB中命中的负载可能不会导致缓冲区被逐出。
为刷新单个WC缓冲区而发生的事务不一定相对于为刷新同一物理核心中的另一WC缓冲区所发生的事务进行排序。即使WC驱逐逻辑被实现为串行驱逐WC缓冲区(这很可能),也不能保证来自不同WC缓冲区的事务最终不会在物理核心域之外交错。
这一切都意味着,即使在同一物理核心中,在同一WC缓冲区和不同WC缓冲区的不同块之间也不能保证持久排序。
导致WC缓冲区被逐出的事件可能因供应商和同一供应商的处理器而异。一些事件是体系结构的(记录在开发人员手册中),而另一些事件是特定于实现的(记录到数据表中)。存储序列化指令是一个同步事件的示例,它确实保证刷新同一逻辑核心上的所有WC缓冲区。传递到逻辑核心的硬件中断是异步事件的一个例子,该事件还导致其所有WC缓冲区被逐出。此外,每个物理或逻辑核心的WC缓冲区的数量取决于实现,并且可以为零。WC缓冲区的大小也取决于实现,并且从架构上讲,可以大于或小于L1D缓存线的大小。此外,WC缓冲区可用于除组合WC写入之外的多种用途,具体取决于微体系结构。
因此,即使您只写完整的WC缓冲区,也不可能确保WC缓冲区只有在变满时才被逐出,以保持原子性,即使在使用单个事务执行完整WC逐出的英特尔处理器上也是如此。
您可以使用MOVDIR64B
来保证原子性,而不是执行多个WC写入指令。MOVDIR64B
不分配WC缓冲区并直接到达目的地,但它可以与已经分配的WC缓冲区组合,在这种情况下,在组合缓冲区和MOVDIR64B
的现有内容之后立即驱逐该缓冲区。在任何情况下,MOVDIR64B
的写入操作总是作为单个事务来执行。请注意,MOVDIR64B
的目标内存操作数需要在64字节边界上对齐。与传统的WC存储类似,MOVDIR64B
与除UC之外的任何其他存储都是弱序的。MOVDIR64B
在TNT、TGL和SPR上得到支持
除了英特尔和AMD处理器上的UC之外,WC/WC+写入不会针对任何内存类型的其他写入进行排序。此外,跨越对齐8字节边界的任何存储器类型的单个写入指令(或写入物理存储器地址空间的指令)本身不能保证在超过对齐8字节的粒度上是原子的。这包括持久原子性。唯一的例外是MOVDIR64B
、ENQCMD
和ENQCMDS
。最后两个与MMIO写入相关。对齐的64字节AVX-512存储可能是持久的原子存储,但这在体系结构上没有保证,不应依赖。