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

标签 c++ optimization cpu-cache

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

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

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

最佳答案

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

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

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

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

现代 CPU 用于缓存使用等的算法非常惊人,并且超出了此处概述的基础知识,因此我认为在实践中您会发现这几乎没有影响。

关于c++ - 如果对象大小 > 缓存行,空间局部性对缓存性能有影响吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50179938/

相关文章:

c++ - 在 WIndows 中从命令提示符运行 QT 应用程序

c++ - 根据属性选择 fstream 或 cout

python - 加速 numpy 小函数

python - 使用 pandas 优化字符串查询。大数据

memory - boost 锁无锁spsc_queue缓存访问

c++ - 在 C++ 中调用临时对象的析构函数的顺序是什么?

c++ - vscode 中没有 c_cpp_properties.json 文件

c - 在优化中迷失/困惑

java - 频繁执行的表达式是否缓存了它的结果?

c++ - "non-native"指针会损害缓存性能吗?