为什么“movnti”后跟一个“sfence”保证持久排序?

Why “movnti” followed by an “sfence” guarantees persistent ordering?

SFENCE prevents NT stores from committing from the store buffer ahead of SFENCE itself.

因此SFENCE只能保证进入LFB的数据顺序

例如,

movnti;
sfence;
movnti to another address;

这里的SFENCE只能保证第一个NT store会比下一个先commit到LFB。但是,由于 LFB 是易失性的,因此数据尚未持久化。进入LFB的数据会按照进入顺序持久化吗?

sfence 确保程序顺序中所有较早的存储在程序顺序中的任何较晚存储变得全局可观察之前变得全局可观察。此处的存储包括数据存储 uops、clflushclflushoptclwbmovdirimovdir64b.

GO 的点数取决于以下所有因素:

  • 操作类型,
  • 存在非时间提示,
  • 目标内存位置的内存类型,
  • 映射到目标内存地址的设备,
  • 微架构。

例如,在现代英特尔服务器处理器上,没有 NT 提示的普通数据存储 uop 目标是映射到主内存的 WB 类型的内存位置,当从内存中获取目标缓存行(如果不存在)时到达 GO在 L1D 中处于合适的一致性状态并且存储被提交到缓存。这就是为什么在英特尔 CSX 等异步 DRAM 刷新 (ADR) 平台上,sfence 本身并不能保证持久性。

关于你问的具体例子,movnti是一个带有NT提示的数据存储指令。假设目标地址映射到 ADR 平台上的主内存,则该指令的全局可观察点与持久域的第一个点相同。因此,在具有 NVDIMM 的任何 Intel 或 AMD 平台上,无论内存类型如何,数据都保证在任何后续存储变为持久化之前位于持久化域中。这比你说的(sfence 防止后面的存储在前面的存储之前提交)更有保障,因为提交并不意味着持久化,但持久化只能发生在提交之后。尽管在这里使用术语“退休”而不是“提交”可能更好,因为“退休”在架构上是有意义的并且表示更改线程的状态,但“提交”是微架构操作并且取决于设计。