当使用写穿透页面缓存策略时

3

我在阅读MDS攻击论文“RIDL: Rogue In-Flight Data Load”。通过将页面设置为写回、写穿、组合写或非缓存,并进行不同实验,确定了线路填充缓冲区是微体系结构泄漏的原因。


顺带一提:我知道内存可以是非缓存的,但是我认为可缓存的数据总是缓存在写回缓存中,即我认为L1、L2和LLC总是写回缓存。

我在我的计算机体系结构书中查阅了写回缓存和写穿缓存的区别。它说:

写穿缓存更容易实现,可以使用独立于缓存的写缓冲区更新内存。此外,由于他们不会触发内存写入,因此读取未命中的成本较低。另一方面,写回缓存结果会减少传输次数,这使得用于执行DMA的I/O设备的内存带宽更大。此外,在向下层级移动且传输时间增加时,减少传输次数变得越来越重要。总的来说,较深层次的缓存更有可能使用写回而不是写穿。

因此,写穿缓存更容易实现。我可以看出这可能是一个优点。但是,如果缓存策略可由页面表属性设置,则不能有实现优势-每个缓存都需要能够在写回或写穿模式下工作。

问题

  1. 每个缓存(L1、L2、LLC)都可以在写回或写穿模式下工作吗?因此,如果将页面属性设置为写穿,则它们都将成为写穿模式吗?
  2. 写组合对于GPU内存很有用;当访问硬件寄存器时,非缓存是好的。何时应将页面设置为写穿?这有什么优点?
  3. 是否有任何写穿缓存(如果它确实是硬件的属性,而不仅仅是由页面表属性控制的东西),还是所有缓存都被创建为写回以减少流量?
1个回答

3
每个缓存(L1、L2、LLC)都可以在写回或写直通模式下工作吗?
在大多数x86微架构中,是的,所有数据/统一缓存都能够进行写回,并且在所有正常DRAM中都使用该模式。intel core i7处理器使用哪种高速缓存映射技术?有一些详细信息和链接。除非另有说明,否则任何谈论x86的人默认假设DRAM页面将是WB。
AMD Bulldozer采用了一种不寻常的选择,使用写直通L1d与一个小的4k写组合缓冲区连接到L2。这有许多缺点,在回顾中被广泛认为是Bulldozer系列的几个弱点或设计错误之一(AMD在Zen中解决了这个问题)。同时请注意,Bulldozer是一项CMT实验,而不是SMT(两个弱整数核共享一个FPU/SIMD单元,每个核有独立的L1d缓存共享一个L2缓存),系统架构如https://www.realworldtech.com/bulldozer/3/所示。
当然,Bulldozer的L2和L3缓存仍然是写回(WB)的,架构师们并不疯狂。写回缓存对于降低共享LLC和内存的带宽需求是必不可少的。即使是写通道(write-through)的L1d也需要一个写组合缓冲区,以便让L2缓存变得更大、更慢,从而在L1d未命中时有时能够命中,达到其目的。另请参见为什么大多数处理器的L1缓存比L2缓存小? 写通道缓存可以简化设计(尤其是单核系统的设计),但通常CPU在几十年前就已经超越了这个阶段。(写回与写通道缓存?)。如果没有写分配(write-allocate)来避免写入污染缓存,一些非CPU负载有时可能会从写通道缓存中受益。x86有NT存储器来避免这个问题。

因此,如果将页面属性设置为写通道,则它们全部都将是写通道吗?

是的,每个商店都必须在标记为WT的页面中进行DRAM全程操作。
缓存被优化为WB,因为这是每个人都使用的方式,但希望支持将行传递到外部缓存而不从L1d中驱逐。因此,WT并不一定会将存储转换为类似于movntps的缓存绕过/驱逐存储。但是请检查一下;显然,在某些CPU上(例如至少是Pentium Pro系列),L1中的WT存储命中会更新该行,但L2中的WT命中却会驱逐该行而不是将其带入L1d。
“什么时候应该将页面设置为写入-直通?有什么优点?”
基本上永远不需要;(几乎?)所有CPU工作负载都最好使用WB内存。
操作系统甚至不费心让用户空间分配WC或WT DRAM页面变得简单(或可能吗?)。(尽管这当然并不能证明它们从来没有用过。)例如,在CPU cache inhibition上,我发现一个链接,介绍了一个Linux补丁,但该补丁从未被合并到主线内核中,该补丁增加了将页面映射为WT的可能性。
WB、WC和UC是常见的普通DRAM、设备内存(尤其是GPU)和MMIO的缓存类型。
我看过至少一篇论文,对某些工作负载进行了WT、WB、UC和WC的基准测试(我搜索了一下,但没有找到,抱歉)。有些人会在测试晦涩的x86内容时包括它,以完整性为例。例如,{{link3:Meltdown背后的微体系结构}}是一篇很好的文章(与您正在学习的相关)。
WT的几个优点之一是,商店很快就会进入L3,其他核心的负载可以击中。这可能值得为每个存储器页面支付额外的成本,特别是如果你小心地将写操作手动组合成一个大的32字节AVX存储器(或64字节AVX512全行写)。当然,只在共享数据的页面上使用它。
我从来没有见过有人建议这样做,也没有尝试过。可能是因为对于大多数用例来说,通过L3进行写入的额外DRAM带宽不值得获得收益。但也可能是因为您可能需要编写内核模块才能以这种方式映射页面。
如果CPU在WT存储器的L2或L3命中时驱逐外部高速缓存,就可能无法完全按照这种方式工作,就像@Lewis评论所述PPro文档中所做的那样。
因此,也许我对WT的目的是错误的,它旨在(或至少可用于)设备内存用例,例如GPU不会修改的视频RAM的某些部分。

1
ioremap_wt 函数用于将页面映射为写入穿透,仅用于一些旧的 fbdev 驱动程序。很有可能这些都是复制粘贴。这支持了你的观点,即 WC 几乎永远不应该被使用。一个惊人的答案。我知道你不应该在评论中使用感谢的话语,但无论如何还是要感谢你! - Daniel Näslund
1
你确定吗?来自奔腾Pro开发手册- WT线是可缓存的,但在写失效时不会进入高速缓存。对WT线的写操作将通过总线传输。对于奔腾Pro处理器,L1缓存的WT命中将更新L1缓存。L2缓存的WT命中将使L2缓存失效。我不知道。这是WP的稍微弱一些的版本。 - Lewis Kelsey
@LewisKelsey:是的,x86 DMA保证具有高速缓存一致性。我不确定WT是否有任何意义;在我的编辑中添加了警告时,我建议可能是设备内存(如视频RAM的某些部分),设备仅读取:您希望CPU写入对设备可见,但读取命中缓存。另一方面,我不确定英特尔CPU是否支持任何可缓存的设备内存。Bandwidth博士评论说,他进行了实验,如果您甚至尝试将PCIe MMIO区域映射为WB,CPU会锁定,我想,或者甚至是WT。或者可能是内存区域,而不仅仅是MMIO;现在找不到评论了。 - Peter Cordes
1
WT 的使用场景是当您需要确保写入尽快发生(而不仅仅停留在缓存中直到被驱逐)。对于这种情况,替代方案是 UC(如果读取可以来自缓存,则明显更差)和“WB 然后 CLFLUSH”(也明显更差)和 WC(也明显更差)。当然,这种用例非常罕见(但我可以想象很快会改变-考虑非易失性 RAM 的电源故障)。 - Brendan
1
@Brendan WT和WP是相同的(它不会污染L2/L3),除了执行未缓存写入时,WT更新而不是逐出L1。因此,如果刚刚读取过,则其基本上是WP,但读取性能更好。与WP相同的DMA性能。比WB+clflush更快地写回。没有clflush比WB更好的DMA性能。@ Peter它不应该锁定,因为那就是CAR,WB设备内存,但它可能与我关于INVD上的SAD所说的有关。它可能在多插座上无法工作,因为它应该将MMIO发送到目标节点IIO并将可缓存的内容发送到目标主代理。 - Lewis Kelsey
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接