std::array 在存储大型对象时是否仍然对缓存友好?

Is std::array still cache friendly when it stores large objects?

本文关键字:缓存 array 存储 大型 std 对象 是否      更新时间:2023-10-16

我知道std::array是缓存友好的,因为存储在std::array中的所有项目都紧密地打包在一起。如果我遍历数组,当我尝试访问一个项目时,CPU 会预取接下来的几个项目。

这就是我的困惑来源:通常 XEON 缓存行是 64 字节:即 8int64_t.成像我有

std::array<BigObject, 100> 

其中每个 BigObject 的大小为 512 字节。在这种情况下,即使所有的 BigObject 项目都彼此相邻打包,CPU 也无法做任何智能的事情:它仍然必须逐行获取缓存,即每个 BigObject 8 行。因此,不应该有任何缓存友好的优势。

那么我的问题是:对于 std::数组的大型对象,是否还有缓存友好性的优势?如果是这样,为什么?

澄清一下,处理器缓存的速度源于这样一个事实,即当今计算机的RAM即内存比CPU慢几倍。所以CPU有一些小的内部存储器,所谓的缓存,速度很快。为了最好地利用小内存,CPU通常使用时间和空间的概念,这意味着经常使用的东西保存在缓存中,而最近使用的东西旁边的东西,它们在内存中的邻居,也被加载到缓存中,因为很可能接下来需要它们。

因此,正如您正确理解的那样,当 紧密位于内存中时,内容会友好地缓存。由于std::arraystd::vector被称为ContiguousContainer,因此它们在内存中将它们的内容彼此相邻保存。

因此,将您经常使用的东西放在一起实际上是缓存友好的,即您在循环中迭代或在这样的容器中一个接一个地使用。

如果你的对象像你说的那么大,你可以做你想做的事,它们太大了,无法放入缓存中,在一个合理的计数中。因此,您可以查看您在这些对象中如此频繁地操作的内容,并且仅将其存储在容器中,或者您可以忍受不可避免的减速。此外,如果您首先在您使用的类或结构中定义最重要的成员,则可以加快速度,因为这会转换为成员存储在内存中的布局。同学们首先要做的是。

但正如所有这些建议的那样,更重要的是:通常你的算法复杂性对程序的整体运行时间更重要。 例如:问你自己,你是编程在每个大对象上做一点工作,然后转到下一个,只是在以后对每个大对象做一些其他的小工作,这是非常低效的,或者你可以一次完成一个对象的所有工作,然后才前进到下一个大对象?如果不是,为什么你的物体这么大?它们不应该只包含手头任务所需的东西吗? 不要把事情搞得一团糟,希望事情会变得更快。"过早优化是万恶之源"是一句流行的话就是这个语境。首先编写清晰易读的程序,并确保正确性。然后运行它并测量它实际上很慢的地方。关于缓存实现的一般推测通常不是很有帮助,启发式的,如"当有疑问时,使用向量或数组,因为它们通常是最快的"就足够了。

或者为了更好地回答您的问题:std::arraystd::vector都是缓存友好性的最佳选择,为什么没有容器可以对大对象进行缓存友好,因为大对象因大而对缓存不友好。