如果对象大小>空间局部性对缓存性能是否重要?缓存线?

时间:2018-05-04 17:05:19

标签: c++ optimization cpu-cache

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

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

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

1 个答案:

答案 0 :(得分:4)

当数据大小小于缓存大小时,在预加载后续项目的好处之外考虑的另一个因素是关联性和映射问题。对于链表,您没有连贯的布局(或者至少不保证这样),因此与使用空间局部布局数据相比,您更有可能遇到冲突。最重要的是,你会冒险使用链表模型来达到内存碎片的水平,尽管我不确定这是否是你应该担心的事情。

根据使用情况,访问模式等,对于您正在进行的操作,绝对值得权衡算法效率的相对优势(删除在链表中非常便宜,在数组或类似代码中很昂贵)。如果您正在进行大量删除/插入,那么算法效率的好处可能远远超过缓存一致性的任何好处。

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

就英特尔/ AMD /等CPU的特定关联性而言,这是一个更加强硬的呼吁,因为即使是英特尔人也很难找到一个好的答案!我发现的一个例子是Xeon x5660 CPU,它是L1中的4路组关联指令,8路组关联数据,L2中的8路组关联,L3中的16路组合。

现代CPU用于缓存使用等的算法非常令人惊讶,并且不仅仅是这里概述的基础知识,所以我认为在实践中你会发现很少有这样的影响。