每个缓存(L1、L2、LLC)都可以在回写或直写模式下工作吗?
在大多数 x86 微架构中,是的,所有数据/统一缓存都(能够)回写,并在该模式下用于所有普通 DRAM。intel core i7处理器使用哪种缓存映射技术?有一些详细信息和链接。除非另有说明,任何谈论 x86 的人都默认假设 DRAM 页面将是 WB。
AMD Bulldozer 做出了非常规的选择,使用直写式 L1d,并在它和 L2 之间有一个小型 4k 写入组合缓冲区。 (https://www.realworldtech.com/bulldozer/8/)。这有很多缺点,我认为(事后看来)被广泛认为是 Bulldozer 系列的几个弱点甚至设计错误之一(AMD 为 Zen 修复了该系列)。另请注意,Bulldozer 是 CMT 而不是 SMT 的实验(两个弱整数核心共享一个 FPU/SIMD 单元,每个核心都有单独的 L1d 缓存,共享一个 L2 缓存)https://www.realworldtech.com/bulldozer/3/显示系统架构。
当然,Bulldozer L2 和 L3 缓存仍然是 WB,架构师并没有疯。WB 缓存对于减少共享 LLC 和内存的带宽需求至关重要。即使是直写式 L1d 也需要一个写入组合缓冲区,以允许 L2 缓存更大且更慢,从而达到 L1d 未命中时有时命中的目的。也可以看看为什么大多数处理器中L1缓存的大小都小于L2缓存的大小?
直写式缓存可以简化设计(尤其是单核系统),但一般来说,CPU 在几十年前就已经超越了这一点。 (回写式缓存与直写式缓存?)。 IIRC,一些非 CPU 工作负载有时会受益于直写式缓存,特别是没有写分配,因此写入不会污染缓存。 x86 有 NT 存储来避免这个问题。
那么如果页面属性设置为write-through,那么它们都会是write-through?
是的,每个存储都必须在标记为 WT 的页面中一直到达 DRAM。
缓存针对 WB 进行了优化,因为这是每个人都使用的,但希望能够支持将线路传递到外部缓存,而无需从 L1d 逐出。 (所以WT不一定把商店变成类似的东西movntps
绕过缓存/驱逐存储。但请检查一下;显然,在某些 CPU 上,至少像 Pentium Pro 系列,L1 中的 WT 存储命中会更新该行,但 L2 中的 WT 命中会驱逐该行,而不是将其带入 L1d。)
何时应将页面设置为直写?这样做有什么好处呢?
基本上从来没有; (几乎?)所有 CPU 工作负载在使用 WB 内存时效果最佳。
操作系统甚至懒得让用户空间轻松(或可能?)分配 WC 或 WT DRAM 页。 (尽管这当然不能证明他们是never有用。)例如在CPU缓存抑制, 我发现a link关于一个从未进入主线内核的 Linux 补丁,该补丁增加了映射页面 WT 的可能性。
WB、WC 和 UC 分别常见于普通 DRAM、设备内存(尤其是 GPU)和 MMIO。
我至少看过一篇论文,针对某些工作量对 WT、WB、UC、WC 进行了基准测试(用 google 搜索,但没有找到,抱歉)。人们测试晦涩的 x86 东西有时会为了完整性而包含它。例如Meltdown 背后的微架构总的来说是一篇好文章(并且与您正在阅读的内容相关)。
WT 的几个优点之一是,存储会立即到达 L3,其他核心的负载可能会受到影响。对于该页面的每个存储来说,这可能是值得的额外成本,特别是如果您小心地将写入操作合并到一个大型 32 字节 AVX 存储中。 (或 64 字节 AVX512 全行写入。)当然,仅将该页面用于共享数据。
不过,我还没有见过有人建议这样做,而且我也没有尝试过。可能是因为对于大多数用例来说,通过 L3 写入的额外 DRAM 带宽并不值得。但也可能是因为您可能必须编写一个内核模块才能以这种方式映射页面。
如果 CPU 从 WT 存储的 L2 或 L3 命中上的外部缓存中逐出,它甚至可能无法完全按照这种方式工作,就像 @Lewis 评论 PPro 记录的那样。
因此,也许我对 WT 的目的的理解是错误的,它旨在(或至少可用)用于设备内存用例,例如 GPU 不会修改的视频 RAM 的部分。