【问题标题】:Write-back vs Write-Through caching?回写与直写缓存?
【发布时间】:2015-01-21 03:59:19
【问题描述】:

我的理解是,这两种方法的主要区别在于,在“write-through”方法中,数据是通过缓存立即写入主存,而在“write-back”方法中,数据是在“稍后”写入”。

我们仍然需要等待“稍后”的内存,那么“直写”有什么好处?

【问题讨论】:

  • @EricWang 我想你的意思是write back 的性能更好?
  • @wlnirvana 是的,你是对的,这是我的笔误。我会删除它,并在此处添加新评论以避免将来产生误导。
  • 简单来说,write back的性能更好,因为写入主存比写入cpu缓存慢很多,而且数据可能会很短(意味着可能会很快再次改变,不需要将旧版本存入内存)。它很复杂,但更复杂,现代 cpu 中的大多数内存都使用此策略。
  • 我看到已经给出了解释性的答案。我建议你在覆盖回写算法之后再看一下 Write-Allocate、Write-NoAllocate 标签。
  • 您的问题的答案是,使用直写缓存,在同一个块内写入时,只需要一次写入主内存。详情见我的回答。

标签: caching cpu-architecture cpu-cache


【解决方案1】:

直写到主存的好处是它简化了计算机系统的设计。使用直写,主存储器始终具有该行的最新副本。因此,当读取完成时,主存总是可以回复请求的数据。

如果使用回写,有时最新数据在处理器缓存中,有时在主内存中。如果数据在处理器高速缓存中,则该处理器必须停止主存储器对读取请求的响应,因为主存储器可能有数据的陈旧副本。这比直写要复杂。

此外,直写可以简化缓存一致性协议,因为它不需要 Modify 状态。 Modify 状态记录了缓存在使缓存行无效或驱逐之前必须写回缓存行。在直写中,缓存行总是可以在不回写的情况下失效,因为内存已经有该行的最新副本。

还有一件事 - 在回写架构上,写入内存映射 I/O 寄存器的软件必须采取额外的步骤,以确保立即将写入发送出缓存。否则写入在内核之外是不可见的,直到该行被另一个处理器读取或该行被驱逐。

【讨论】:

  • 对于内存映射 I/O,这些地址通常映射为未缓存的。直写也可用于提高可靠性(例如,如果 L1 仅具有奇偶校验保护而 L2 具有 ECC)。对于使用无写分配的较小缓存(即写未命中不会将块分配给缓存,可能会减少对 L1 容量和 L2 读/L1 填充带宽的需求),直写也更受欢迎,因为大部分硬件此类写入已经存在写入要求。
  • 是否可以检查我的核心中的缓存方法是回写还是直写?
  • 说回写更复杂可能会产生误导,因为处理器必须阻止主内存响应读取请求。更重要的是,缓存通过使用“脏位”来跟踪哪些数据是数据(未与主存对齐),哪些不是,因此可能根本不检查主存。
  • @Shaowu "lshw" 命令显示缓存功能,如“异步内部回写”
  • 我仍然不明白回写中使用的真正步骤是什么,但只知道它很复杂......你能提供更多关于它的资源/细节吗?
【解决方案2】:

回写是一种更复杂的方法,需要复杂的缓存一致性协议 (MOESI),但它是值得的,因为它使系统快速高效。

Write-Through 的唯一好处是它使实现极其简单,并且不需要复杂的缓存一致性协议。

【讨论】:

  • WT 仍然需要一致性协议。来自一个核心的存储仍然需要使其他缓存中的副本无效,这样它们就不会无限期地读取陈旧的数据。 Atomic RMW 需要一些特殊的支持。我认为,使用 WT 所有这些都更容易,但所需的一致性仍然有些复杂。
  • 或者您可能在谈论具有 L1 / L2 缓存层次结构的单核系统(也许更多)。在这种情况下,您实际上不必将 MESI/MOESI 用于通过外部缓存获取的内部缓存,除非您想要支持可以访问最外部缓存方向的缓存一致 DMA。但是,您仍然需要 DMA 写入的一致性才能使内部缓存无效。
  • 只有在需要支持多个缓存/处理器或影响内存(如 DMA)时才需要缓存一致性协议。直写即使对于单处理器系统也有其优势,即写入速度。
  • 对于 DMA,操作系统可以在 I/O 之后显式刷新缓存。作为软件,它的效率较低。
【解决方案3】:

让我们通过一个例子来看看这个。 假设我们有一个直接映射缓存并且使用了回写策略。所以我们在高速缓存行中有一个有效位、一个脏位、一个标签和一个数据字段。 假设我们有一个操作:写 A(其中 A 映射到缓存的第一行)。

发生的情况是来自处理器的数据(A)被写入缓存的第一行。设置有效位和标记位。脏位设置为 1。

脏位只是表示自从上次将缓存线带入缓存后,该缓存线是否被写入!

现在假设执行另一个操作:读取 E(其中 E 也映射到第一个缓存行)

由于我们有直接映射缓存,第一行可以简单地替换为将从内存中取出的 E 块。但是由于最后写入行的块(块A)还没有写入内存(由脏位表示),所以缓存控制器会首先向内存发出回写进行传输块 A 到内存,然后它将通过向内存发出读取操作来用块 E 替换该行。脏位现在设置为 0。

所以回写策略不能保证块在内存和它相关的缓存行中是相同的。然而,每当该行即将被替换时,首先执行回写。

直写策略正好相反。据此,内存将始终有最新的数据。也就是说,如果缓存块被写入,内存也会相应地被写入。 (不使用脏位)

【讨论】:

    【解决方案4】:

    希望这篇文章能帮到你Differences between disk Cache Write-through and Write-back

    直写:写入缓存和后备存储同步完成。

    回写(或后写):仅对缓存进行写入。修改后的缓存块在被替换之前被写回存储区。

    Write-through:数据更新时,会同时写入缓存和后端存储。这种模式操作简单,但数据写入速度慢,因为数据要同时写入缓存和存储。

    回写:数据更新时,只写入缓存。仅当从缓存中删除数据时,才会将修改后的数据写入后端存储。此模式的数据写入速度快,但如果在更新数据写入存储之前发生断电,数据将丢失。

    【讨论】:

    • 我没有听从最后一句话的解释。在电源故障时,无论是直写还是回写,DRAM 也会丢失数据,因此这不应该是回写特定问题。
    • @gustafbstrom 并非所有内存都是 DRAM。
    • @gustafbstrom 我认为这个解释是从内存/磁盘而不是缓存/内存的角度来看的。但是,概念是一样的。
    • @gustafbstrom 回写是一种更危险的方法,如果您断电并且缓存中没有备用电池。事情是直写也可能丢失数据。我认为最安全的方法是关闭所有写入缓存并仅使用读取缓存。
    【解决方案5】:

    写回和直写描述了发生写命中时的策略,即当缓存具有请求的信息时。在这些示例中,我们假设单个处理器正在使用缓存写入主内存。

    Write-through:信息被写入缓存和内存,当两者都完成时写入完成。这样做的好处是实现起来更简单,并且主内存始终与缓存一致(同步)(对于单处理器情况 - 如果其他一些设备修改了主内存,那么这个策略是不够的),并且读取未命中永远不会导致写入主内存。明显的缺点是每次写入命中必须执行两次写入,其中一次访问速度较慢的主内存。

    回写:信息被写入缓存中的一个块。修改后的缓存块仅在被替换时才写入内存(实际上,延迟写入)。每个缓存块的一个特殊位 dirty bit 标记缓存块在缓存中是否已被修改。如果不设置脏位,则缓存块是“干净的”,写入未命中不必将该块写入内存。

    优点是可以以高速缓存的速度进行写入,如果在同一个块内写入,则只需要一次写入主内存(当前一个块被替换时)。缺点是该协议较难实现,主存可能与缓存不一致(不同步),导致替换的读取可能会导致将脏块写入主存。

    write miss 的政策在我的第一个链接中有详细说明。

    这些协议无法处理现代处理器中常见的多处理器和多缓存的情况。为此,需要更复杂的缓存一致性机制。直写缓存具有更简单的协议,因为对缓存的写入会立即反映在内存中。

    好资源:

    【讨论】:

      猜你喜欢
      • 2019-11-05
      • 1970-01-01
      • 1970-01-01
      • 2021-04-29
      • 1970-01-01
      • 1970-01-01
      • 2018-06-24
      • 1970-01-01
      • 2014-05-06
      相关资源
      最近更新 更多