背景: 我正在开发一个光线追踪器.. 对于我构建的空间划分方案,我最初有一些代码如下:
if (msize <= 2) { // create a leaf node
Model **models = new Model*[msize];
for (uint i=0; i<msize; ++i)
models[i] = &mlist[i];
*arrayPtr = Node(models, msize); // class Node contains a copy of models
... increment arrayPtr ...
return;
}
基本上,在构建空间划分树之后,光线会遍历树查找模型,这些模型都存储在一个大数组中。叶节点包含指向模型的指针数组的指针。
然后我意识到,嘿,我没有理由添加那个额外的间接级别;如果我正确地排列我的模型,我可以让叶节点直接指向模型的大数组。在大数组中相邻的模型都属于给定的叶节点,因此叶节点将包含指向模型的指针。所以我这样做了,并测试了一切其他内容都保持不变。
现在人们可能认为这显然会加快程序的速度。好吧,它确实加快了单线程版本(约10%),但它减慢了多线程版本(约15%!如果你正在进行重度优化,这是非常重要的)。我很迷茫如何解决这个问题——我认为间接寻址是不好的,我认为减少内存使用对于多线程来说尤其是好的......根本没有对叶节点或模型进行任何写入,所有写入都是针对单独的数据结构进行的。
关于如何分析问题的任何指针/建议都将是很棒的。
一些杂项统计数据:cachegrind告诉我,双重间接方法的指令引用/缓存未命中要少一些,但数据引用/缓存未命中要多一些。不过,两者之间的差异并不是很大。
编辑:根据请求,我关心的数据结构如下:
class Node {
ushort type;
union {
ushort axisID;
ushort childrenSize;
};
union {
Model **models;
Node *rightChild;
};
float leftPlane, rightPlane;
... public methods and stuff ...
}
我基本上将 Model **models
改为了 Model *models
,然后就出现了速度降低的情况。类 Model
本身包含指向两个抽象类 Shape
和 Material
的指针。所有提到的类都是块分配的,除了 Material
,因为目前我只使用了一个。