SFENCE 防止 NT 存储在 SFENCE 本身之前从存储缓冲区提交。
因此 SFENCE 只能保证数据进入 LFB 的顺序。
例如,
movnti;
sfence;
movnti to another address;
这里的 SFENCE 只能保证第一个 NT 存储将比下一个更早地提交到 LFB。但是,由于 LFB 是易失性的,因此数据尚未持久化。进入LFB的数据会按照进入的顺序持久化吗?
SFENCE 防止 NT 存储在 SFENCE 本身之前从存储缓冲区提交。
因此 SFENCE 只能保证数据进入 LFB 的顺序。
例如,
movnti;
sfence;
movnti to another address;
这里的 SFENCE 只能保证第一个 NT 存储将比下一个更早地提交到 LFB。但是,由于 LFB 是易失性的,因此数据尚未持久化。进入LFB的数据会按照进入的顺序持久化吗?
sfence
确保程序顺序中的所有早期存储在程序顺序中的任何后续存储变得全局可观察之前成为全局可观察的。这里的存储包括数据存储 uops、clflush
、clflushopt
、clwb
、movdiri
和movdir64b
。
GO 的意义取决于以下所有因素:
例如,在现代英特尔服务器处理器上,如果目标缓存行在 L1D 中尚未存在,则在从内存中获取目标缓存行时,没有 NT 提示的普通数据存储 uop 到达 GO合适的一致性状态和存储提交到缓存。这就是为什么在英特尔 CSX 等异步 DRAM 刷新 (ADR) 平台上,sfence
其本身并不能保证持久性。
关于您要询问的具体示例,movnti
是带有 NT 提示的数据存储指令。假设目标地址映射到 ADR 平台上的主存,则该指令的全局可观察点与持久域的第一个点相同。因此,在任何带有 NVDIMM 的 Intel 或 AMD 平台上,无论内存类型如何,都可以保证在以后的任何存储变为持久之前,数据都在持久域中。这是比你说的更有力的保证(即sfence
防止以后的存储在较早的存储之前提交),因为提交并不意味着持久性,但持久性只能在提交之后发生。尽管在这里使用术语“retire”而不是“commit”可能会更好,因为“retire”在架构上是有意义的,并表示更改线程的状态,但“commit”是一种微架构操作,取决于设计。