通过使用标记为 WB(回写)和 WC(写结合)的内存的指令之间的主要区别是什么:MOVDQA
和之间有什么不同,和MOVNTDQA
之间有什么不同?VMOVDQA
VMOVNTDQ
对吗,对于内存已标记为 WC - 指令与[NT]
平时没有什么不同(没有[NT]
),并且该内存被标记为 WB -[NT]
与它一起使用的指令就好像它是一个内存 WC?
NT
在写入内存映射 IO(即:GPU 等)时,您通常会使用(非临时)指令,其中内存是严格不可缓存的,并且始终可以直接访问。
通过定期读取和写入,CPU 将在需要时尝试缓存更大的块并将其写入主内存。对于不可缓存的区域(例如 MMIO),写入必须直接进入内存,CPU 不会尝试缓存它们。使用NT
指令向 CPU 提示您可能正在流式传输大量数据(即:到帧缓冲区等),当它可以填充整个缓存行时,它将尝试组合这些写入。
“非临时”部分意味着您告诉 CPU 您不打算立即进行写入,但可以在合理范围内延迟写入,直到NT
发出足够的指令来填充高速缓存行。
据我了解,您还可以将NT
指令与常规回写内存一起使用,它不会尝试缓存这些写入,但也会在它可以填满一行时尝试流式传输。在写入 WB 内存的情况下,我会说应用程序将非常专业,您需要知道在管理其缓存方面您可以比 CPU 做得更好。此外,写入不会立即发生,因此之后读取的任何内容都会读取陈旧数据,直到执行组合写入。SFENCE
如果您需要刷新任何未完成的组合写入,则需要 使用说明进行管理。
最好直接从英特尔那里阅读——他们有很多关于这个主题的信息:
但是,在使用非临时指令时要注意处理器勘误表,如果您需要针对内存屏障(例如 LOCK ADD、MFENCE)对它们进行排序。
勘误表 HSD162、BDM116 和 SKL079 适用,请参阅 Haswell/Broadwell/Skylake 规范更新。基本上,来自 WC 内存的非临时 MOVNTDQA 将绕过 Haswell/Broadwell 上的 LOCK,您必须使用 MFENCE 来修复。在 Skylake 上,它以另一种方式被破坏,因此来自 WC 内存的非临时 MOVNTDQA 将绕过 MFENCE,修复方法是更新 Skylake 微码......