0

动态和经典多维数组的使用(不是创建)速度在速度方面是否不同?

我的意思是,例如,当我尝试在循环的帮助下访问三维数组中的所有值时,作为动态方法和经典方法创建的数组之间是否存在速度差异。

当我说“动态三维数组”时,我的意思是matris_cos[kuanta][d][angle_scale]是这样创建的。

matris_cos = new float**[kuanta];
for (int i = 0; i < kuanta; ++i) {
  matris_cos[i] = new float*[d];

  for (int j = 0; j < d; ++j)
    matris_cos[i][j] = new float[angle_scale];
}

当我说“经典的三维数组”时,我的意思是matris_cos[kuanta][d][angle_scale]就是这样创建的。

float matris_cos[kuanta][d][angle_scale];

但请注意,我不问这些数组的创建速度。我想通过一些循环访问这些数组的值。当我尝试访问这些值时是否有任何速度差异。

4

2 回答 2

1

除非您的数组非常庞大并且您花费大量时间读取/写入它们,否则您将无法在典型的应用程序中发现它们之间的任何差异,但是仍然存在差异。

float matris_cos[kuanta][d][angle_scale];

1) 这个多维数组的内存是连续的。结果将减少缓存未命中。
2) 数组只需要浮点数本身的空间。

matris_cos = new float**[kuanta];
for (int i = 0; i < kuanta; ++i) {
    matris_cos[i] = new float*[d];

    for (int j = 0; j < d; ++j)
        matris_cos[i][j] = new float[angle_scale];
}

1) 这个多维数组的内存是按块分配的,因此不太可能是连续的。这可能会导致缓存未命中。
2) 这种方法需要指针和浮点数本身的空间。

由于在第二种情况下存在间接性,因此您在尝试访问或更改值时可能会出现微小的速度差异。

回顾一下:

  • 第二种情况使用更多内存
  • 第二种情况涉及间接
  • 第二种情况没有保证缓存位置。
于 2013-07-24T10:57:45.533 回答
1

指针数组(指向指针数组)将需要额外的间接级别来访问随机元素,而多维数组将需要基本算术(乘法和指针加法)。在大多数现代平台上,除非您使用缓存友好的访问模式,否则间接可能会更慢。此外,多维数组的所有元素都是连续的,如果您遍历整个数组,这可能有助于缓存。

这种差异是否可测量,您只能通过测量来判断。

如果额外的间接性确实被证明是一个瓶颈,您可以用一个类替换指针数组,以用平面数组表示多维数组:

class array_3d {
    size_t d1,d2,d3;
    std::vector<float> flat;

public:
    array_3d(size_t d1, size_t d2, size_t d3) : 
        d1(d1), d2(d2), d3(d3), flat(d1*d2*d3) 
    {}

    float & operator()(size_t x, size_t y, size_t z) {
        return flat[x*d2*d3 + y*d3 + z];
    }
    // and a similar const overload
};

我相信下一个 C++ 标准(将于明年发布)将包括动态大小的数组,因此您应该能够在所有情况下使用多维形式。

于 2013-07-24T11:04:23.360 回答