我知道std :: array是缓存友好的,因为存储在std :: array中的所有项目彼此紧紧地包装在一起。如果我遍历数组,当我尝试访问一项时,CPU将预取接下来的几项。
这是我感到困惑的地方:通常XEON缓存行是64字节:8 int64_t。成像我有
std::array<BigObject, 100>
每个BigObject的大小为512字节。在这种情况下,即使所有BigObject项都紧挨着打包,CPU也将无法做任何聪明的事:它仍然必须逐行获取缓存,即每个BigObject 8行。因此,不应有任何缓存友好的优势。
我的问题是:对于大型对象的std :: array,仍然存在缓存友好性的优点吗?如果是这样,为什么?
我们需要澄清的是,处理器缓存的加速源于以下事实:RAM,即当今计算机的内存比CPU慢几倍。因此,CPU具有一些小的内部存储器,即所谓的高速缓存。为了最有效地利用小内存,CPU通常使用时间和空间的概念,这意味着将常用的东西保存在缓存中,并且将最近使用的东西旁边的东西(它们在内存中的邻居)也加载到缓存中。 ,因为下一步很有可能需要它们。
因此,正如您所理解的那样,当它们紧密位于内存中时,事物将被友好地缓存。由于std::array
和std::vector
被称为ContiguousContainer,因此它们的内容在内存中彼此相邻。
因此,将”。
然而,如果对象的大小与您说的一样大,则可以执行所需的操作,因为对象太大而无法容纳到高速缓存中,且数量合理。因此,您可以查看在这些对象中如此频繁地操作并将它们仅存储在容器中的原因,或者不可避免地受到影响。另外,如果您首先在所使用的类或结构中定义最重要的成员,则可以加快速度,因为这会转换为成员存储在内存中的布局。对于班级成员来说,第一件事首先。但是所有这些建议都更为重要:通常,算法的复杂性对于程序的整体运行时间要重要得多。例如:问问自己,您编程要对每个大对象做一点工作,然后转到下一个对象,然后再对每个大对象做一些其他工作,这效率很低,或者您是否可以做所有的工作?一次找到一个对象,然后才转到下一个大对象?如果没有,为什么您的对象这么大?它们不应该只是包含手头任务所需的东西吗?不要凌乱地指责事情,希望事情会更快。 “过早的优化是万恶之源”是这种情况的流行语录。首先,编写程序要清晰,易读且正确。然后运行它并测量它实际上在哪里变慢。通常,关于缓存实现的一般猜测不是很有帮助,像“当有疑问时使用向量或数组,因为它们通常是最快的”这样的启发式就足够了。
或者为了更好地回答您的问题:std::array
和std::vector
都是高速缓存友好的最佳选择,但是对于大对象来说,没有容器对高速缓存友好,因为大对象由于大而对高速缓存不友好。 >