std::array 在存储大型对象时是否仍然对缓存友好?
Is std::array still cache friendly when it stores large objects?
我知道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::array
和std::vector
被称为ContiguousContainer,因此它们在内存中将它们的内容彼此相邻保存。
因此,将您经常使用的东西放在一起实际上是缓存友好的,即您在循环中迭代或在这样的容器中一个接一个地使用。
如果你的对象像你说的那么大,你可以做你想做的事,它们太大了,无法放入缓存中,在一个合理的计数中。因此,您可以查看您在这些对象中如此频繁地操作的内容,并且仅将其存储在容器中,或者您可以忍受不可避免的减速。此外,如果您首先在您使用的类或结构中定义最重要的成员,则可以加快速度,因为这会转换为成员存储在内存中的布局。同学们首先要做的是。
但正如所有这些建议的那样,更重要的是:通常你的算法复杂性对程序的整体运行时间更重要。 例如:问你自己,你是编程在每个大对象上做一点工作,然后转到下一个,只是在以后对每个大对象做一些其他的小工作,这是非常低效的,或者你可以一次完成一个对象的所有工作,然后才前进到下一个大对象?如果不是,为什么你的物体这么大?它们不应该只包含手头任务所需的东西吗? 不要把事情搞得一团糟,希望事情会变得更快。"过早优化是万恶之源"是一句流行的话就是这个语境。首先编写清晰易读的程序,并确保正确性。然后运行它并测量它实际上很慢的地方。关于缓存实现的一般推测通常不是很有帮助,启发式的,如"当有疑问时,使用向量或数组,因为它们通常是最快的"就足够了。
或者为了更好地回答您的问题:std::array
和std::vector
都是缓存友好性的最佳选择,为什么没有容器可以对大对象进行缓存友好,因为大对象因大而对缓存不友好。
- cmake更新缓存的变量
- 试图对缓存进行跨步测试,但程序并没有结束
- 缓存std::数组的选定元素,并在c++中自动保持其一致性
- 通过ccmake在cmake中缓存依赖选项
- C++11 中不同类型的对象的 std::array 的替代方案
- constexpr begin of a std::array
- C++如果必须在编译时确定大小,std::array 有什么意义?
- OpenGL VBO Indexing ( How to compute Index Array)
- 标准::unordered_map 中的 std::array 的值初始化
- "Warning: Comma within array index expression"但逗号分隔函数参数
- 确保编译时的特定 std::array 位置
- std::array的长度有大小限制吗?
- 将 std::array 移动到另一个 std::array
- 首先按给定顺序打印所有数字,然后使用 Array 打印所有字符和其他符号
- 使用宏扩展的泛型:为什么指令缓存使用不当?
- 如何使缓存线程安全
- 为什么 std::shared_ptr 被认为是"heavy"和"expensive",但 std::array "same perfprmance as plain (c-style) arrays
- 将 **float array 从 C++ Dll 传递给 python
- std::bind on statd::array 的运算符 []
- std::array 在存储大型对象时是否仍然对缓存友好?