ST64B 和 MOVDIR64B 的暂时性

Temporality of ST64B and MOVDIR64B

x86_64 有一条指令 movdir64b,根据我的理解,它是一个 64 字节(高速缓存行)的非临时副本(好吧,至少存储是)。 AArch64 似乎有一个类似的指令 st64b,它执行相同大小的原子存储。但是,官方 ARMv9 文档并不清楚 st64b 是否也是非临时存储。

Intel 的指令集参考 documentation for movdir64b 更详细,但我的研究还不够深入,无法完全理解每种内存类型协议代表什么。

目前为止我可以推断,x86_64 指令 movntdq 大致等同于 stnp,并且是写组合。由此看来,似乎 movdir64b 就像一个原子存储中的四个,因此我猜测 st64b.

这几乎可以肯定是对实际情况的过度简化(当然也可能 wrong/inaccurate),但这是目前可以推断出的结果。

是否可以将 st64b 用作四个 stnp 指令的原子序列,以这种方式作为高速缓存行的非临时写入?

ST64B/ST64BV/ST64BV0 指令旨在有效地将工作项添加到支持此接口的 I/O 设备的工作队列中。当目标地址映射到 I/O 设备时,存储被转换为 non-posted 写入事务,这意味着必须有一个包含状态代码的完成消息,如文档中所述。 ST64B 指令简单地丢弃状态代码,而其他两个将其存储在由 Xs 操作数指定的寄存器中。

如果您查看 pseudocode,这些指令要求目标地址位于不可缓存的内存中:

if acctype == AccType_ATOMICLS64 && memattrs.memtype == MemType_Normal then
    if memattrs.inner.attrs != MemAttr_NC || memattrs.outer.attrs != MemAttr_NC then
        fault.statuscode = Fault_Exclusive;
        return (fault, AddressDescriptor UNKNOWN);

否则,生成的状态代码为 0xFFFFFFFF_FFFFFFFF,如文档中所述,它表示目标地址不支持原子 64 字节存储。请注意,这与表示失败的状态代码 1 不同。发生这种情况的原因有很多。例如,目标设备的工作队列已满。

我从伪代码的理解是,只要目标地址在不可缓存的内存中,这些指令就可以在普通内存和设备内存上使用。您应该通过检查状态代码来实验性地检查它们是否真的在正常内存上工作。

这些指令与ARM的STNP和x86的MOVNTDQ完全不同。 x86中对应的指令是MOVDIR64BENQCMDENQCMDS。尽管 ARM 和 x86 之间存在重大差异。如果您是为了目的而不是行为,那么您在这些说明之间进行的“心理等价”是可以的。