C++中的快速内存访问?

Tia*_*sta 6 c++ memory memory-management

在C++中快速内存访问方面开发游戏时应该考虑什么?

我加载的内存是静态的,所以我应该放入一个连续的内存块吗?

另外,我应该如何组织结构中的变量以提高性能?

Mat*_* M. 11

内存性能非常模糊.

我认为您正在寻找的是关于处理CPU缓存,因为缓存中的访问和主内存中的访问之间存在大约10倍的因素.

有关缓存背后机制的完整参考,您可能希望阅读Ulrich Drepper在lwn.net上发表的这篇优秀系列文章.

简而言之:

瞄准地方

你不应该在内存中跳转,所以尽量(如果可能的话)将要一起使用的项目组合在一起.

瞄准可预测性

如果您的内存访问是可预测的,则CPU可能会预取内存以进行下一个工作块,以便在完成当前块之后立即或稍后可用.

典型的例子是for数组上的循环:

for (int i = 0; i != MAX; ++i)
  for (int j = 0; j != MAX; ++j)
    array[i][j] += 1;
Run Code Online (Sandbox Code Playgroud)

改变array[i][j] += 1;,array[j][i] += 1;并且性能会有所不同......在低优化级别;)

编译器应该捕获那些明显的情况,但有些更隐蔽.例如,使用基于节点的容器(链表,二进制搜索树)而不是基于数组的容器(向量,一些哈希表)可能会降低应用程序的速度.

不要浪费空间......谨防虚假分享

尝试收拾你的结构.这与对齐有关,并且由于结构中的对齐问题,您可能会浪费空间,这会人为地夸大结构大小并浪费缓存空间.

一个典型的经验法则是通过减小尺寸(使用sizeof)来订购结构中的项目.这是愚蠢的,但效果很好.如果您对尺寸和路线更了解,请避免漏洞:) 注意:仅对具有大量实例的结构有用...

但是,要小心虚假分享.在多线程程序中,对足够接近共享同一缓存线的两个变量的并发访问是昂贵的,因为它涉及大量缓存失效和CPU争夺缓存线所有权.

轮廓

不幸的是,这是HARD弄清楚.

如果您碰巧在Unix上编程,Callgrind(Valgrind套件的一部分)可以使用缓存模拟运行,并识别触发缓存未命中的代码部分.

我想还有其他工具,我从来没用过它们.


Mar*_*rkR 6

你不在乎.这些事情很可能是对最小性质的微观优化.首先让它工作,如果它太慢,那么找出哪些部分很慢,并优化它们(提示:这可能是你调用库等的方式,而不是内存访问).

  • @DevSolar -1如果可以的话.在许多情况下,组织内存访问不是过早的优化. (4认同)
  • OP关心:否则他不会在StackOverflow上问这个问题. (3认同)
  • +1."过早优化是万恶之源." - D. Knuth (2认同)