C中计算有效的三维数组

时间:2008-09-16 19:36:51

标签: c arrays multidimensional-array numerical

我试图在数值上解决一组三维偏微分方程。在每个方程中,一个点中未知的下一个值取决于最近点中每个未知数的当前值。

要编写一个有效的代码,我需要保持三维中的点靠近(一维)内存空间,这样每个值只需从内存中调用一次。

我正在考虑使用octtrees,但我想知道是否有人知道更好的方法。

3 个答案:

答案 0 :(得分:5)

八叉树是要走的路。您将数组细分为8个八分圆:

1 2
3 4

---

5 6
7 8

然后按照上面的顺序1,2,3,4,5,6,7,8将它们放在记忆中。你在每个八分圆中递归地重复这个,直到你达到一个基本大小,大概大约128个字节左右(这只是一个猜测 - 确保分析以确定最佳截止点)。与天真的布局相比,这具有更好,更好的缓存一致性和参考局部性。

答案 1 :(得分:5)

树方法的一种替代方法:使用Morton-Order对数据进行编码。

在三维中它是这样的:取坐标分量并将每个位交错两个零位。这里以二进制显示:11111b变为1001001001b

执行此操作的C函数如下所示(为清楚起见,仅显示11位):

int morton3 (int a)
{
  int result = 0;
  int i;
  for (i=0; i<11; i++)
  {
     // check if the i'th bit is set.
     int bit = a&(1<<i);
     if (bit)
     {
       // if so set the 3*i'th bit in the result:
       result |= 1<<(i*3);
     }
  }
  return result;
}

您可以使用此功能组合您的位置:

index = morton3 (position.x) + 
        morton3 (position.y)*2 +
        morton3 (position.z)*4;

这会将您的三维索引转换为一维索引。最佳部分:3D空间中接近的值也在1D空间内接近。如果你经常访问彼此接近的值,你也会得到一个非常好的加速,因为在缓存局部性方面,morton-order编码是最佳的。

对于morton3,你最好不要使用上面的代码。使用小表一次查找4或8位并将它们组合在一起。

希望它有所帮助,   尼尔斯

答案 2 :(得分:3)

本书Foundations of Multidimensional and Metric Data Structures可以帮助您确定哪种数据结构最适合范围查询:八叉树,kd树,R树,...... 它还描述了将点保持在内存中的数据布局。