【问题标题】:why are separate icache and dcache needed [duplicate]为什么需要单独的 icache 和 dcache [重复]
【发布时间】:2012-02-01 04:25:17
【问题描述】:

谁能解释一下我们通过单独的指令缓存和数据缓存获得了什么。 任何指向解释这一点的良好链接的指针也将不胜感激。

【问题讨论】:

  • 一个用于数据,一个用于指令:两者都可能以不同的速率“流失”,并具有不同的访问模式。
  • From Wikipedia: “指令和数据缓存可以分离,以提高哈佛 CPU 的性能,但也可以将它们结合起来以减少硬件开销。”总是不同。
  • 这里有一个有趣的消息是,JIT 可以通过通过数据缓存写出指令来产生问题,或者当检索指令时它们不在内存/较低的共享缓存中,或者指令高速缓存可能有过时的指令。您必须手动处理同步。

标签: caching x86 cpu-architecture cpu-cache


【解决方案1】:

由于处理器的 MEM 和 FETCH 阶段可以同时访问 L1 缓存(假设合并),因此可能会出现优先级冲突(可能成为性能瓶颈)。解决此问题的一种方法是使 L1 缓存具有两个读取端口。但是增加端口的数量会二次增加缓存区域,因此会增加功耗。

此外,如果 L1 缓存是组合缓存,那么某些数据块可能会替换包含重要且即将被访问的指令的块。这些驱逐和后续缓存未命中可能会损害整体性能。

此外,大多数情况下,处理器按顺序获取指令(很少有例外,如获取目标、跳转等),这为指令缓存提供了更多的空间局部性,从而提高了命中率。此外,正如其他答案中提到的,几乎没有任何写入 ICache(自修改代码,如 JIT 编译器)。因此,单独的 icache 和 dcache 设计可以根据它们的访问模式和其他组件(如加载/存储队列、写入缓冲区等)进行优化。

【讨论】:

  • 自修改代码不直接写入I-cache,它必须使其无效。 (在 I-cache 不一致的大多数非 x86 ISA 上手动使用特殊指令)。 L1I-cache 通常是只读的,标签不需要空间来存放脏位。 (并且不需要支持字节访问。)唯一的 I-cache 写入端口可以连接到从 L2 获取,而无需将其与来自 CPU 内核的写入复用。另见What does a 'Split' cache means. And how is it useful(if it is)?
【解决方案2】:

架构一般有2种,1.冯诺依曼架构,2.哈沃德架构。硬件架构使用 2 个独立的存储器。你可以在这个手臂页面上获得更多信息http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka3839.html

【讨论】:

    【解决方案3】:

    主要原因是:性能。另一个原因是功耗。

    单独的 dCache 和 iCache 使得并行获取指令和数据成为可能。

    指令和数据有不同的访问模式。

    写入 iCache 的情况很少见。 CPU 设计人员基于代码更改很少的假设优化 iCache 和 CPU 架构。例如,AMD Software Optimization Guide for 10h and 12h Processors 声明:

    预解码在 L1 指令缓存被填满时开始。预解码信息与指令缓存一起生成并存储。

    Intel Nehalem CPU 具有环回缓冲区,除此之外,Sandy Bridge CPU 还具有 µop 缓存 The microarchitecture of Intel, AMD and VIA CPUs。请注意,这些是与代码相关的功能,与数据没有直接对应关系。它们有利于性能,并且由于英特尔“禁止”CPU 设计人员引入导致功耗过度增加的功能,因此它们可能也有利于总功耗。

    大多数 CPU 都具有数据转发网络(存储到负载转发)。没有与代码相关的“存储加载转发”,仅仅是因为代码的修改频率远低于数据。

    代码表现出与数据不同的模式。

    也就是说,现在大多数 CPU 都有统一的 L2 缓存,可以同时保存代码和数据。这样做的原因是,拥有单独的 L2I 和 L2D 缓存会毫无意义地消耗晶体管预算,同时无法提供任何可衡量的性能提升。

    (当然,将 iCache 和 dCache 分开的原因并没有降低复杂性,因为如果原因是降低复杂性,那么当前任何 CPU 设计中都不会有任何流水线。A带流水线的 CPU 比不带流水线的 CPU 更复杂。我们希望增加复杂性。事实是:下一个 CPU 设计(通常)比以前的设计更复杂。)

    【讨论】:

    • 我指的是缓存控制器的复杂性。
    • 写入 I-cache 不仅很少见,而且在大多数 CPU 设计中几乎是不可能的;它可以构建为只读的,不需要标签中的额外空间来跟踪数据是否“脏”。 ECC 粒度可以任意大。 (当然数据必须在缓存未命中时通过驱逐进入和离开,并从外部缓存中获取,所以它仍然需要一个“写端口”)
    • 存储转发是从存储缓冲区完成的,而不是 L1d 缓存。无论 L1 是拆分还是统一,它的工作原理都是一样的。此外,“数据转发网络”通常是指从执行单元到执行单元的旁路转发(而不是等待回写+寄存器读取)。不过,这个答案的顶部是正确的:关键原因是读取和写入端口:并行使用的两个较小的缓存比构建一个具有读取和写入端口总和的较大缓存要便宜得多。
    【解决方案4】:

    一个原因是降低了复杂性 - 您可以实现一个共享缓存,它可以一次检索多行,或者只是异步检索(请参阅 Hit-Under-Miss),但这会使缓存控制器更加复杂。

    另一个原因是执行稳定性 - 如果您有已知数量的 icache 和 dcache,数据缓存不会使指令缓存系统饿死,这可能发生在简单的共享缓存中。

    正如 Dan 所说,将它们分开会使流水线更容易,而不会增加控制器的复杂性。

    【讨论】:

      【解决方案5】:

      这与 CPU 的哪些功能单元主要访问该缓存有关。由于 ALU 和 FPU 访问的是解码器和调度器访问指令缓存的数据缓存,并且通常流水线允许指令处理器和执行单元同时工作,因此使用单个缓存会导致这两个组件之间的争用。通过将它们分开,我们失去了一些灵活性,并获得了处理器的这两个主要组件同时从缓存中获取数据的能力。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-12-28
        • 2023-03-15
        • 2016-09-03
        • 2023-03-29
        • 1970-01-01
        相关资源
        最近更新 更多