我在 this 中阅读了缓存的拆分设计与统一设计的优缺点线程。
根据我的理解,拆分设计的主要优点是:拆分设计使我们能够将指令缓存放置在靠近指令获取单元的位置,将数据缓存放置在靠近内存的位置单元,从而同时减少两者的延迟。主要缺点是:指令和数据缓存的组合空间可能无法得到有效利用。仿真表明,相同总大小的统一缓存具有更高的命中率。
但是,我无法找到“为什么(至少在大多数现代处理器中)L1 缓存遵循分离设计,而 L2/L3 缓存遵循统一设计”这个问题的直观答案。
最佳答案
分割 L1 的大部分原因是为了在两个缓存之间分配必要的读/写端口(以及带宽),并将它们物理地放置在靠近数据加载/存储与管道的指令获取部分的位置。
L1d 还可以处理字节加载/存储(在某些 ISA 上,未对齐的更宽加载/存储)。在想要 handle that with maximum efficiency 的 x86 CPU 上(不是包含字的 RMW),Intel 的 L1d 只能使用奇偶校验,而不使用 ECC。 L1i 只需要处理固定宽度的提取,通常是一些简单的东西,比如对齐的 16 字节 block ,并且它总是“干净”,因为它是只读的,所以它只需要检测错误(不正确) ),然后重新获取。因此,每行数据的开销较小,例如每 8 或 16 字节只需几个奇偶校验位。
参见Why is the size of L1 cache smaller than that of the L2 cache in most of the processors?回复:不可能构建一个大型统一 L1 缓存,其容量是分离 L1i/d 的两倍、相同的延迟和带宽总和。(由于功耗至少高得令人望而却步)读/写端口的大小和数量,但由于物理距离的原因,实际上可能不可能出现延迟。)
这些因素对于 L2 都不重要(或者在未对齐/字节存储的情况下根本不存在)。可用于代码或数据的总容量在那里最有用,根据需求竞争性共享。
任何工作负载在同一时钟周期内出现大量 L1i 和 L1d 缺失的情况都是非常罕见的,因为频繁的代码缺失意味着前端停滞,后端将耗尽要执行的加载/存储指令。 (频繁的 L1i 缺失很少见,但频繁的 L1d 缺失在某些正常工作负载中确实会发生,例如循环遍历不适合 L1d 的数组、大型哈希表或其他更分散的访问模式。)无论如何,这意味着数据可以正常情况下可以获得大部分L2总带宽预算,统一的L2仍然只需要1个读端口。
您链接的@Hadi 的答案确实涵盖了大部分原因,但我想写一个简化/摘要的答案并没有什么坏处。
关于caching - L1缓存通常是分体式设计,而L2、L3缓存却是统一设计,为什么呢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64184265/