assembly - 为什么 Ice Lake 没有像 tremont 那样的 MOVDIRx?他们已经有更好的了吗?

标签 assembly x86 intel cpu-architecture instruction-set

我注意到英特尔 特里蒙特 MOVDIRI 的 64 字节存储指令和 MOVDIR64B .
这些保证原子写入内存,而 不要保证负载原子性。此外,写入是弱排序的,可能需要紧跟其后的防护。
我发现没有 MOVDIRx在冰湖。

为什么不冰湖需要像 MOVDIRx 这样的说明?

(在第 15 页底部)
英特尔® 架构指令集扩展和 future 功能编程引用
https://software.intel.com/sites/default/files/managed/c5/15/architecture-instruction-set-extensions-programming-reference.pdf#page=15

最佳答案

Ice Lake 有 AVX512,它为我们提供了 64 字节的加载 + 存储,但不能保证 64 字节的存储原子性。

我们确实通过 movntps [mem], zmm 获得了 64 字节的 NT 存储/ movntdq [mem], zmm .有趣的是,NT 存储不支持合并屏蔽以保留一些字节未写入。但是,这基本上会通过创建部分行写入来破坏 NT 存储的目的。

可能 Ice Lake Pentium/Celeron CPU 仍然不会有 AVX1/2,更不用说 AVX512(可能是因为他们可以销售在 FMA 单元的高 128 位和/或至少一个内核上的寄存器文件中存在缺陷的芯片),所以只有rep movsb将能够在这些 CPU 上内部使用 64 字节的加载/存储。 (IceLake 将具有“快速短表示”功能,这可能使其即使对于小的 64 字节副本也很有用,在不能使用向量寄存器的内核代码中很有用。)

可能英特尔无法(或不想)在其主流 CPU 上提供原子性保证,仅在不支持多插槽的低功耗芯片上提供,但我还没有听到任何有关撕裂实际存在的报告Intel CPU 上的缓存线。实际上,我认为在当前 Intel CPU 上不跨越缓存线边界的缓存加载/存储总是原子的。

(与 AMD K10 不同,HyperTransport 确实在插槽之间的 8B 边界上产生撕裂,而在单个插槽上的内核之间看不到撕裂。
SSE instructions: which CPUs can do atomic 16B memory operations? )

在任何情况下,都无法通过 CPUID 检测到这一点,并且没有记录在案,因此基本上不可能安全地利用这一点。如果有一个 CPUID 叶告诉您系统和单个套接字内的原子性宽度会很好,因此仍然允许将 512 位 AVX512 操作分成 256 位一半的实现......

无论如何,与其引入具有保证存储原子性的特殊指令,我认为 CPU 供应商更有可能开始为所有 2 次幂大小的存储或仅为 NT 记录和提供更广泛的存储原子性的 CPUID 检测商店,什么的。

使 AVX512 的某些部分需要 64 字节原子性将使 AMD 更难支持,如果他们遵循他们目前的半角向量实现策略。 (Zen2 将有 256 位向量 ALU,使 AVX1/AVX2 指令主要是单微操作,但不幸的是,据报道它不会支持 AVX512。AVX512 是一个非常好的 ISA,即使您只在 256 位宽度下使用它,填补可以方便/有效地完成的更多空白,例如 unsigned int<->FP 和 [u]int64<->double。)

所以 IDK 如果英特尔同意不这样做,或者出于自己的原因选择不这样做。

64B 写入原子性的用例:

我怀疑主要用例是可靠的 创建 64 字节 PCIe 事务 ,实际上并不是“原子性”本身,也不是用于另一个核心的观察。

如果您关心从其他内核读取,通常您希望 L3 缓存支持数据,而不是将其绕过到 DRAM。 seqlock 可能是模拟 CPU 内核之间 64 字节原子性的更快方法,即使 movdir64B可用。

Skylake 已经有 12 个写入组合缓冲区(从 Haswell 中的 10 个增加),因此(也许?)使用常规 NT 存储来创建全尺寸 PCIe 事务并避免早期刷新并不太难。但是,也许低功耗 CPU 的缓冲区较少,并且可靠地创建 64B 事务到 NIC 缓冲区或其他东西可能是一个挑战。

关于assembly - 为什么 Ice Lake 没有像 tremont 那样的 MOVDIRx?他们已经有更好的了吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54919280/

相关文章:

assembly - 访问汇编中寄存器的高阶字节

assembly - 为什么地址是0xF000 :0xE05B in the long jump instruction located at 0xFFFF0 in BIOS?

linux - 确定用于构建 ATLAS 的独立 CPU(用关联 ID 指定)

intel - AMD 与 Intel 处理器制作可执行文件

汇编语言用法

c - 使用gcc直接编译成机器码,无需链接

assembly - x86 多字节 NOP 和指令前缀

英特尔 CPU 上的 OpenCL 管道

debugging - 您最喜欢的反调试技巧是什么?

assembly - 128 位值 - 从 XMM 寄存器到通用