相关:在具有一些但有限的空间局部性的典型访问模式的更一般情况下,较大的线在一定程度上有所帮助。这些 "Memory Hierarchy: Set-Associative Cache" (powerpoint) 幻灯片由 Hong Jiang 和/或 Yifeng Zhu(美国缅因州)提供了 AMAT(平均内存访问时间)与块大小的曲线图,同时也打破了它归结为未命中惩罚与未命中率(我认为对于一个简单的模型,对于一个简单的有序 CPU,它在隐藏内存延迟方面很糟糕。例如,甚至可能没有流水线处理多个独立的未命中。(未命中下的未命中))
在这些幻灯片中很多好东西,包括提到循环交换的编译器优化部分(以修复列优先与行优先顺序的嵌套循环),甚至缓存阻塞以实现更多重用。互联网上的很多东西都是废话,但我浏览了这些幻灯片,它们提供了一些关于如何设计缓存以及权衡取舍的可靠信息。性能分析的东西只对简单的 CPU 真正准确,不像现代的乱序 CPU,它可以与缓存未命中延迟重叠一些计算,因此较短的未命中与较少的较长未命中是不同的。
这个问题的具体答案:
所以您唯一关心的工作负载是元素的线性遍历?假设良好的硬件预取,这使得高速缓存行大小与性能几乎无关。 (因此,更大的线路意味着相同性能的硬件复杂性和功耗更低。)
使用软件预取,更大的行意味着更少的预取开销(尽管取决于 CPU 设计,如果您仍然最大限度地利用内存带宽,这可能不会影响性能。)
在没有任何预取的情况下,更大的行/块大小将意味着在每次需求未命中后会有更多的命中。数组的单次遍历具有完美的空间局部性,没有时间局部性。 (实际上,如果数组未与缓存行的开头对齐,和/或在行的中间结束,则在开始/结束处的空间局部性实际上并不完美。)
如果未命中必须等到整个行都存在于缓存中才能满足导致未命中的负载,这会略微降低较大块的优势。 (但缓存未命中的大部分延迟在于信令和请求开销,而不是等待突发传输已经开始后完成。)
更大的块大小意味着在相同带宽和延迟的情况下运行中的请求更少,而有限的并发性是实际 CPU 中内存带宽的真正限制因素。 (有关 x86 内存带宽,请参阅此答案的latency-bound platforms 部分:对 L3 缓存具有较高延迟的多核 Xeon 的单线程带宽低于相同时钟速度的双核或四核。每个内核只有 10 行-填充缓冲区以跟踪未完成的 L1 未命中和bandwidth = concurrency / latency。)
如果您的缓存未命中处理具有提前重启设计,那么即使是那一点额外的延迟也可以避免。 (这很常见,但保罗说theoretically possible to not have it in a CPU design)。导致丢失的负载一到达就得到它的数据。缓存行的其余部分填充“在后台”发生,希望以后的加载也可以从部分接收的缓存行中得到满足。
Critical word first 是一个相关功能,首先发送所需的字(用于提前重启),然后突发传输回绕以传输块的较早字。在这种情况下,关键字始终是第一个词,因此除了提前重启之外不需要特殊的硬件支持。 (我在上面链接的 U. Maine 幻灯片首先提到了提前重启/关键词,并指出它减少了大型缓存行的未命中惩罚。)
无序执行 CPU(或按顺序 CPU 上的软件流水线)可以通过同时处理多个未完成的需求未命中来为您提供相当于硬件预取的功能。如果 CPU“看到”另一个缓存行的负载,而当前缓存行的未命中仍然未完成,则可以对需求未命中进行流水线化,再次隐藏较大或较小行之间的一些差异。
如果行太小,L1D 可以跟踪的不同行的未完成未命中数会受到限制。对于较大的行或较小的无序窗口,当没有对下一个缓存行的未完成请求时,您可能会有一些“松弛”,因此您不会最大化带宽。当你到达缓存行的末尾并且下一行的开始还没有到达时,你会用管道中的气泡来支付它,因为它开始得太晚了(而 ALU 执行单元使用的数据距离太近当前缓存行的结尾。)
相关:these slides 不用多说大线与小线的权衡,但看起来还不错。