Ice Lake 有 AVX512,它为我们提供了 64 字节的加载和存储,但不能保证 64 字节的存储原子性。
我们确实获得了带有movntps [mem], zmm / movntdq [mem], zmm 的 64 字节 NT 存储。有趣的是,NT 存储不支持合并屏蔽以保留一些未写入的字节。不过,这基本上会通过创建部分行写入来破坏 NT 存储的目的。
Ice Lake Pentium / Celeron CPU 可能仍然没有 AVX1/2,更不用说 AVX512(可能是为了销售在 FMA 单元的高 128 位和/或至少一个内核上注册文件存在缺陷的芯片),因此只有 rep movsb 能够在这些 CPU 上内部使用 64 字节加载/存储。 (IceLake 将具有“快速短表示”功能,这可能使其即使对于小的 64 字节副本也很有用,在不能使用向量 reg 的内核代码中很有用。)
可能英特尔不能(或不想)在其主流 CPU 上提供原子性保证,仅在不支持多个插槽的低功耗芯片上提供,但我没有没有听到任何关于英特尔 CPU 缓存行中实际存在撕裂的报告。在实践中,我认为在当前英特尔 CPU 上不跨越缓存线边界的缓存加载/存储始终是原子的。
(与 AMD K10 不同,在 AMD K10 上,HyperTransport 确实在插槽之间的 8B 边界上产生撕裂,而在单个插槽上的内核之间看不到撕裂。
SSE instructions: which CPUs can do atomic 16B memory operations?)
无论如何,使用 CPUID 无法检测到这一点,并且没有记录在案,因此基本上不可能安全地利用它。如果有一个 CPUID 叶告诉您系统和单个套接字内的原子性宽度,那就太好了,因此仍然允许将 512 位 AVX512 操作分成 256 位两半的实现....
无论如何,与其引入保证存储原子性的特殊指令,我认为 CPU 供应商更有可能开始记录并为所有 2 次方大小的存储提供更广泛的存储原子性的 CPUID 检测,或者仅适用于 NT 商店或其他什么的。
如果 AMD 遵循其当前的半角向量实现策略,则使 AVX512 的某些部分需要 64 字节原子性将使 AMD 难以支持。 (Zen2 将具有 256 位向量 ALU,使 AVX1/AVX2 指令主要是单 uop,但不幸的是,据报道它不会支持 AVX512。AVX512 是一个非常好的 ISA,即使您只以 256 位宽度使用它,填补了可以方便/有效地完成的更多空白,例如 unsigned intFP 和 [u]int64double。)
如果英特尔同意不这样做,或者出于他们自己的原因选择不这样做,那么 IDK。
64B 写入原子性用例:
我怀疑主要用例是可靠地创建 64 字节 PCIe 事务,实际上并不是“原子性”本身,也不是供其他内核观察的。
如果您关心从其他内核读取数据,通常您会希望 L3 缓存支持数据,而不是将其绕过到 DRAM。 seqlock 可能是在 CPU 内核之间模拟 64 字节原子性的更快方法,即使 movdir64B 可用。
Skylake 已经有 12 个写入组合缓冲区(在 Haswell 中为 10 个),因此(也许?)使用常规 NT 存储来创建全尺寸 PCIe 事务并避免过早刷新并不难。但也许低功耗 CPU 的缓冲区较少,并且可靠地为 NIC 缓冲区或其他东西创建 64B 事务可能是一个挑战。