【发布时间】:2016-01-29 09:29:27
【问题描述】:
我目前正在研究面向数据的设计/实体-组件-系统,并考虑将其应用于某些算法,如果不是整个程序的话。
在低层次上,我了解这种设计如何允许编写通过缓存使用高效内存访问的代码。
我见过很多这样的例子:
// position is a (x,y) coordinate pair
for ( int i=0; i!=position_count; ++i ) {
do_something_with(position[i]);
}
我明白了。我们不是遍历所有“胖”对象(带有 x,y,state,name,hp 等...),而是遍历该对象的一小部分(这里是单个位置 x,y)。 这些位置包含在一个连续的内存位置(一个数组)中。代码看起来很高效:数据很少,所有内容都在一个循环中读取,允许 L1 缓存完成其工作。
现在理论上这看起来很完美,但在一个真实世界的例子中,我想知道它是如何工作的。
在这个例子中:
// visual is a (x,y) coordinate pair
// and also contain an index to the sprite array
for ( int i=0; i!=visual_count; ++i ) {
sprite s = sprites[visual[i].sprite_id];
s.draw_at( visual[i].x, visual[i].y );
}
在这里,我们使用读取的数据来做一些有用的事情。 但这会导致读取第二个内存位置(精灵)。
Sprite 可能包含比一对坐标(宽度、高度、纹理位置等)更多的数据。 此外,精灵数组很可能是相当随机的访问。
它不会“破坏”之前遍历位置的缓存吗? L1、L2、L3 缓存有哪些内容? 在这种情况下编写高效代码的最佳方法是什么?
【问题讨论】:
标签: caching memory optimization