在使用 C++ 快速访问内存方面开发游戏时应该考虑什么?
我加载的内存是静态的,所以我应该放入一个连续的内存块中,对吧?
另外,我应该如何组织结构中的变量以提高性能?
最佳答案
内存性能非常模糊。
我认为您正在寻找的是关于处理 CPU 缓存,因为在缓存中的访问和主内存中的访问之间存在大约 10 倍。
有关缓存背后机制的完整引用,您可能希望阅读 Ulrich Drepper on lwn.net 的这篇优秀文章系列。 .
简而言之:
瞄准地方
您不应该在内存中乱跳,因此请尝试(如果可能)将要一起使用的项目组合在一起。
以可预测性为目标
如果您的内存访问是可预测的,则 CPU 可能会为下一个工作 block 预取内存,以便在完成当前 block 后立即或很快可用。
典型的例子是在数组上使用 for
循环:
for (int i = 0; i != MAX; ++i)
for (int j = 0; j != MAX; ++j)
array[i][j] += 1;
将 array[i][j] += 1;
更改为 array[j][i] += 1;
并且性能会有所不同......在低优化级别;)
编译器应该捕捉到那些明显的情况,但有些情况更隐蔽。例如,使用基于节点的容器(链表、二叉搜索树)而不是基于数组的容器( vector 、一些哈希表)可能会降低应用程序的速度。
不要浪费空间...谨防虚假分享
尝试打包您的结构。这与对齐有关,您可能会因为结构中的对齐问题而浪费空间,这会人为地增大结构大小并浪费缓存空间。
一个典型的经验法则是通过减小大小对结构中的项目进行排序(使用 sizeof
)。这很愚蠢,但效果很好。如果您对大小和对齐方式有更多了解,请避免空洞:) 注意:仅对具有大量实例的结构有用...
但是,请注意虚假分享。在多线程程序中,并发访问足够接近以共享同一缓存行的两个变量的成本很高,因为它涉及大量缓存失效和 CPU 争夺缓存行所有权。
个人资料
不幸的是,这很难弄清楚。
如果你碰巧在 Unix 上编程,Callgrind
(Valgrind 套件的一部分)可以通过缓存模拟运行并识别触发缓存未命中的代码部分。
我猜还有其他工具,我只是没用过。
关于c++ - C++中的快速内存访问?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6762610/