【问题标题】:Computationally efficient three dimensional arrays in CC中计算高效的三维数组
【发布时间】:2010-09-09 17:13:15
【问题描述】:

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

要编写高效的代码,我需要将三个维度中的点保持在(一维)内存空间中的附近,以便从内存中调用每个值一次。

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

【问题讨论】:

    标签: c arrays multidimensional-array numerical


    【解决方案1】:

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

    1 2 3 4 --- 5 6 7 8

    然后按照上面的 1、2、3、4、5、6、7、8 的顺序将它们放在内存中。您在每个八分圆内递归地重复此操作,直到您减小到某个基本大小,可能约为 128 个字节左右(这只是一个猜测——确保分析以确定最佳截止点)。与朴素布局相比,这具有更好的缓存一致性和引用局部性。

    【讨论】:

      【解决方案2】:

      Foundations of Multidimensional and Metric Data Structures 这本书可以帮助您确定哪种数据结构对于范围查询最快:八叉树、kd-trees、R-trees... 它还描述了将点放在内存中的数据布局。

      【讨论】:

        【解决方案3】:

        树方法的一种替代方法:使用 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 位并将它们组合在一起。

        希望对你有帮助, 尼尔斯

        【讨论】:

        • 这似乎是八叉树的一个很好的替代品,但在我的特殊情况下,我认为我会坚持树的简单性。无论如何感谢您的回答,我不知道这种方法!
        猜你喜欢
        • 2011-08-03
        • 2023-03-12
        • 1970-01-01
        • 2017-04-03
        • 2012-12-05
        • 2017-10-24
        • 1970-01-01
        • 1970-01-01
        • 2023-03-05
        相关资源
        最近更新 更多