我正在使用C ++编写的应用程序,该应用程序必须处理存储在连续内存空间中的某些数据,这些数据被解释为3D数组。 为了进行有效的数据处理,我必须更改内存中的数据顺序。
所以这是一个例子:
原始数据位于内存中,我可以通过数据指针(uint16_t*
)来访问数据,该数据指针被解释为3D数组,并具有以下尺寸:
xSize=4, ySize=4, zSize=3
数据在内存中的位置如下:(d x,y,z )
d_ 0,0,0 | d_ 1,0,0 | d_ 2,0,0 | d_ 3,0,0 | d_ 0,1,0 | d_ 1,1,0 | d_ 2,1,0 | d_ 3,1,0 | .... | d_ 3,0,2 | d_ 3,1,2 | d_ 3,2,2 | d_ 3,3,2 |
现在我想按z,y,x的顺序获取数据:
d_ 0,0,0 | d_ 0,0,1 | d_ 0,0,2 | d_ 0,1,0 | d_ 0,1,1 | d_ 0,1,2 | .... | d_ 2,3,2 | d_ 3,3,0 | d_ 3,3,1 | d_ 3,3,2 |
我执行了以下循环:
for (uint32_t z = 0; z < zSize; z++) {
for (uint32_t y = 0; y < ySize; y++) {
for (uint32_t x = 0; x < xSize; x++) {
uint32_t readPos = z * xSize * ySize + y * xSize + x;
uint32_t outPos = y * xSize * zSize + x * zSize + z;
*(dataOutPtr + outPos) = *(dataInPtr + readPos);
}
}
}
有人知道如何加快此算法的速度吗? 是否可以在并发执行中执行某些部分,或者有人知道另一种3D数据重新排序的解决方案?
答案 0 :(得分:2)
这必然是一种粗暴的算法。循环要么在源中具有良好的缓存局部性,要么在目标中具有良好的缓存局部性,但不能两者兼有。具有讽刺意味的是,这也许也是为什么要重新安排数据以在使用时获得更适当的缓存位置的原因,但是直到真正完成重新安排原始布局后,您的速度才会变慢。
显然,您必须访问每个元素,并且您最里面的循环体将具有与预期一样的性能。
也许可以并行化这—因为我在那里不了解,所以其他人将不得不探索—但是从基本的C ++角度来看,我认为您已经在尽力而为。至少,除非您可以预处理或修复源数据,或者除非可以完全不进行重新安排(例如,如果您实际上不关心缓存局部性,因此可以简单地将索引方案更改为外观),< / p>