如果对象大小 > 缓存行,空间局部性对缓存性能有影响吗?

Does spatial locality matter for cache performance if object size > cache line?

假设我正在存储对象的链接列表,每个对象都是一个大小为 64 字节的结构,这也是我的缓存行的大小。随着时间的推移,我将对链表进行对延迟敏感的添加、删除和迭代。我知道性能取决于对象是否保存在缓存中,因此访问 RAM 的访问是 ~1 nano 而不是 >50 nano。

通常建议使用空间局部性来完成此操作,理想情况下将对象存储在连续的内存块中。这很有用,因为每当我访问内存地址时,处理器实际上都会提取缓存行的数据;我们希望这些额外的数据成为其他有用的对象,因此我们将所有对象放在一个连续的块中。

我可能误会了,但如果对象大小 >= 缓存行大小,我们似乎无法从这种效果中获益。一次只能将一个对象放入缓存。

除了在数据大小小于缓存大小时预加载后续项目的好处之外,另一个需要考虑的因素是关联性和映射问题。在链表的情况下,您没有连贯的布局(或者至少不能保证这样),因此与数据以空间局部性布局相比,您更有可能发生冲突。最重要的是,链接列表模型确实存在内存碎片级别的风险,尽管我不确定这是否是您应该担心的事情。

根据使用情况、访问模式等,对于您正在做的事情,绝对值得权衡算法效率的相对优势(删除在链表中非常便宜,在数组或类似物中很昂贵)。如果您正在做很多 deleting/inserting,那么算法效率的好处可能远远超过缓存一致性带来的任何好处。

阐明结合律的概念,值得一看here。基本上,缓存的关联性决定了特定地址可以映射到缓存中的多少个位置。不同的缓存级别将具有不同的关联性,因此例如在大多数情况下,L1 缓存是 2 路或 4 路组关联的,这意味着任何地址都可以映射到缓存中的两个(或四个)位置之一。 L2 和 L3 更可能是 8(或有时 12 或 16)路关联。

至于 Intel/AMD/etc CPU 的特定结合性,这是一个更难的决定,因为即使是 Intel 的人也很难想出一个好的答案!我发现的一个例子是 Xeon x5660 CPU,它是 L1 中的 4 路集合关联指令,8 路集合关联数据,L2 中的 8 路集合关联,L3 中的 16 路集合关联。

现代 CPUs 用于缓存使用等的算法非常惊人,并且超出了此处概述的基础知识,所以我认为在实践中你会发现它的影响很小.