【问题标题】:Are the subscripts for three-dimensional arrays strictly defined?三维数组的下标是否严格定义?
【发布时间】:2010-03-06 02:13:20
【问题描述】:

假设我声明了这一点:

int [a][b][c];

a 代表级别/页面,b 代表行,c 代表列吗?

或者它可以是我想要的任何东西,即 a 代表列,b 代表页面,c 代表行(因为数据只是数据,并且可以以任何方式抽象出一个立方体)?

【问题讨论】:

  • 它们可以代表任何你想要的东西,以任何顺序。
  • C++ 是行优先的怎么办?这有效果吗?
  • 但是考虑一下典型用法并相应地优化设计。例如,在 C、C++ 和其他语言中,N 维内存很可能被分配为连续的一维数组。因此,在迭代此数组时,您需要牢记内存分页和 MRU 缓存。希望有人能比我更好地解释这一点。
  • @Brandon,这并不意味着什么——在 C/C++ 中,只有一维数组。多维数组只是数组的数组,它们不是某种特殊类型,就像在其他环境中一样。
  • @Brandon,是的 row-major-ism 将/可以影响您的数据访问/检索/修改的性能。好问题。

标签: c++ multidimensional-array


【解决方案1】:

任何你想要的任何你想要的顺序,行和列的名称只是惯例。内存中的布局将在 C++ 中为http://en.wikipedia.org/wiki/Row-major_order,该部分无法更改。

在许多情况下,您如何迭代元素会对性能产生影响。您想更改最内层循环中最右边的索引以按顺序在内存中移动。

【讨论】:

  • 我不认为内存中的布局看起来像 C/C++ 多维数组。第一维是一个指针数组,每个指针指向一个一维数组;没有可以依赖的连续内存布局。
  • Carl,不涉及指针,只涉及数组。数组元素是连续存储的。
  • 你仍然想像 000,001,002 一样迭代 .. 而不是 000, 100, 200, 300 ... 如果这有意义的话。
  • @Carl:这不是真的。 C 和 C++ 都允许您将多维数组定义为连续内存。限制是,当将它们作为参数传递时,除了最后一个维度(在本例中为 3 个中的 2 个)之外的所有维度都是类型的一部分,因此只有最后一个维度在运行时可以是可变的。
  • @Hamish:是的,这就是我所说的最内层循环中最右边的索引的意思。
【解决方案2】:

如果你定义:

int my_array[10][10][10];

需要的一件事是索引相对于存储的含义。 my_array[1][2][3] 在内存中与my_array[1][2][4] 相邻,但与my_array[1][3][3] 不相邻。 my_array[2][2][3] 距离更远。当您增加一个或另一个索引时,这可能会影响性能 - 增加最后一个索引通常会更快,因为您会获得更多的缓存命中。

例子:

const int K = 400;
int my_array[K][K][K];

int main() {
    for (int i = 0; i < K; ++i) {
        for (int j = 0; j < K; ++j) {
            for (int k = 0; k < K; ++k) {
                #ifdef FAST
                    my_array[i][j][k] = 12;
                #else
                    my_array[k][j][i] = 12;
                #endif
            }
        }
    }
}

输出:

$ g++ looporder.cpp -o looporder && time ./looporder

real    0m2.500s
user    0m2.249s
sys     0m0.155s

$ g++ looporder.cpp -o looporder -DFAST && time ./looporder

real    0m0.516s
user    0m0.327s
sys     0m0.124s

$ g++ looporder.cpp -o looporder -O3 && time ./looporder

real    0m2.234s
user    0m2.140s
sys     0m0.093s

$ g++ looporder.cpp -o looporder -DFAST -O3 && time ./looporder

real    0m0.250s
user    0m0.171s
sys     0m0.108s

就实际存储的内容而言,索引的含义取决于您 - 正如您所说,这只是您的多维数据集“向上”的问题。因此,通常您选择它们​​,以便在最内层循环中增加的任何内容都是最后一个维度。

【讨论】:

    猜你喜欢
    • 2017-12-23
    • 2019-06-29
    • 1970-01-01
    • 2018-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-05
    • 2019-04-02
    相关资源
    最近更新 更多