我还没有玩过这个,但我从文档中得到的理解是,对于加载(与 NT 存储不同),没有什么可以绕过缓存或覆盖像普通 WB(回写)这样的内存类型的强排序。甚至 NT 也存储了已经缓存的数据,因此它们不能破坏这个或另一个为你正在编写的行缓存数据的内核的一致性。
您可以从 WC(写入组合)内存区域(使用 prefetchnta 或 SSE4 movntdqa)执行弱排序加载,但它们在物理地址级别可能仍然是连贯的。
@MargaretBloom 评论
IIRC Intel 警告开发人员关于不同缓存类型的多个映射,在这种情况下这可能确实很好。
因此,也许您实际上可以通过同一物理页面的多个虚拟映射绕过缓存一致性。
我不知道是否仍然可以使用 PCI / PCIe 设备进行非连贯 DMA,但这可能是您在不通过缓存的情况下获取实际 DRAM 内容的唯一希望。(现代 x86 系统上的大多数(?)DMA 是缓存一致的,这对性能有好处,并且可能因为内存控制器内置在 CPU 中。因此在 Intel CPU 上,系统代理可以窥探 L3 标签以查看是否存在行缓存在芯片上的任何位置,与将请求发送到内存控制器并行。)
有一条INVD
指令会在不先进行回写的情况下使所有缓存无效,但我认为这包括共享的 L3 缓存,可能还有所有其他核心的私有缓存。因此,您实际上无法在其他内核可能正在执行操作的 Linux 系统上使用它;您可能会通过使用它来破坏内核数据结构,以及在具有NVDIMM的机器上为您感兴趣的进程模拟电源故障。
也许如果您以某种方式使所有其他 CPU 内核脱机,并禁用仍在运行的一个内核上的中断
然后重新启用中断。如果wbinvd
在invd
.
更新:有人确实尝试过这个: