SFENCE prevents NT stores from committing from the store buffer ahead of SFENCE itself.
NT store data enters an LFB directly from the store buffer.
因此SFENCE只能保证进入LFB的数据的顺序。
例如,
movnti;
sfence;
movnti to another address;
这里的SFENCE只能保证第一个NT store会比下一个先commit到LFB。但是,由于 LFB 是 volatile 的,因此数据尚未持久化。进入LFB的数据会按照进入顺序持久化吗?
最佳答案
sfence
确保程序顺序中所有较早的存储在程序顺序中的任何较晚存储变得全局可观察之前变得全局可观察。这里的存储包括数据存储 uops、clflush
、clflushopt
、clwb
、movdiri
和 movdir64b
.
GO 的点数取决于以下所有内容:
- 操作类型,
- 非时间暗示的存在,
- 目标内存位置的内存类型,
- 映射到目标内存地址的设备,以及
- 微架构。
例如,在现代 Intel 服务器处理器上,当从内存中获取目标缓存行(如果尚未存在于L1D 处于合适的一致性状态并且存储被提交到缓存。这就是为什么在 Intel CSX 等异步 DRAM 刷新 (ADR) 平台上,sfence
本身并不能保证持久性。
关于您询问的具体示例,movnti
是带有 NT 提示的数据存储指令。假设目标地址映射到 ADR 平台上的主内存,则该指令的全局可观察点与持久域的第一个点相同。因此,在具有 NVDIMM 的任何 Intel 或 AMD 平台上,无论内存类型如何,数据都保证在任何后续存储变为持久化之前位于持久化域中。这比你说的(sfence
防止后面的存储在前面的存储之前提交)更有保障,因为提交并不意味着持久化,但持久化只能发生在提交之后。虽然在这里使用术语“退出”而不是“提交”可能更好,因为“退出”在架构上是有意义的并且表示更改线程的状态,但“提交”是微架构操作并且取决于设计。
关于x86 - 为什么 “movnti” 后跟一个 “sfence” 保证持久排序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65826035/