假设非临时存储的解析内存类型是 WC(或 WC+),这就是我认为您要问的问题,答案主要不在 Intel 和 AMD 处理器上。
对于英特尔处理器,英特尔 SDM V2 第 11.3.1 节中的某些语句指定了在具有至少一个 WC 缓冲区的微架构上进行写组合写入的行为。
驱逐 WC 缓冲区的协议取决于实现
软件不应依赖它来实现系统内存一致性。
这是一个一般性的声明,表示 WC 驱逐的原因和为驱逐 WC 缓冲区而执行的事务是依赖于实现的。但手册中不同地方都有具体的说明。
同样 [如 P6],对于从这些开始的较新的处理器
基于Intel NetBurst微架构,完整的WC缓冲区将
始终使用任何块作为单个突发事务进行传播
交易中的订单。
如果同一个 WC 缓冲区中的所有字节都是有效的,这意味着自分配缓冲区以来每个字节至少被写入一次,当缓冲区因任何原因被逐出时,缓冲区中的整个缓存行将使用单个事务逐出。如果缓冲区的目标是内存控制器(它是 CLX 上持久化域中的第一个单元),则事务的所有字节都将被持久化,或者不会持久化任何字节。这意味着已写入该行的写入指令的程序顺序将保持不变。这些特定写入和其他写入之间的顺序将在稍后讨论。
当事务的目标是存储器控制器时,在此上下文中的“在事务内使用任何块顺序”部分从软件的角度来看并不重要,但对于其他目标来说很重要。
Intel 已指定所有微架构上的块大小均按 8 字节对齐。此块大小仅适用于核心和非核心互连,但不适用于其他协议实现的范围。但对于针对 IMC 的写入,持久原子性在事务的粒度上得到保证,事务的粒度可能包含 1 到 64 字节(所有现代 Intel 和 AMD 处理器上的 WC 缓冲区的大小都是 64 字节),具体取决于当缓冲区被逐出时,同一 WC 缓冲区内有效字节的分布,具体取决于确切的逐出协议。在 Intel 处理器上,在 WC 缓冲区被完全驱逐的情况下,事务保证包含所有 64 个有效字节。
AMD手册只说满了WC缓冲区驱逐can作为单个事务执行。
以下引用指定了部分 WC 缓冲区逐出(其中并非所有字节在缓冲区中都标记为有效)情况下的排序保证以及不同 WC 缓冲区中的写入之间的排序。它适用于 Intel 和 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 逐出的 Intel 处理器上也是如此。
您可以使用MOVDIR64B
,保证了原子性。MOVDIR64B
不分配 WC 缓冲区并直接前往目的地,但它可能与已分配的 WC 缓冲区组合,在这种情况下,在组合缓冲区的现有内容和MOVDIR64B
。无论如何,写操作MOVDIR64B
始终作为单个事务执行。请注意,目标内存操作数MOVDIR64B
需要在 64 字节边界上对齐。与传统的WC店类似,MOVDIR64B
与除 UC 之外的任何其他商店都是弱排序的。MOVDIR64B
TNT、TGL 和 SPR 支持。
WC/WC+ 写入不会相对于任何内存类型的其他写入进行排序,除了 Intel 和 AMD 处理器上的 UC 之外。此外,跨越对齐 8 字节边界的任何内存类型的单个写入指令(或写入物理内存地址空间的指令)本身不保证在超出对齐 8 字节的粒度上是原子的。这包括持久原子性。唯一的例外是MOVDIR64B
, ENQCMD
, and ENQCMDS
。最后两个与进行 MMIO 写入时相关。对齐的 64 字节 AVX-512 存储很可能是持久原子的,但这在架构上没有得到保证,因此不应依赖。