【问题标题】:Why is there such a big execution time difference between these two implementation of multi-dimensional arrays? [duplicate]为什么这两种多维数组的实现会有这么大的执行时间差呢? [复制]
【发布时间】:2016-10-23 07:20:30
【问题描述】:

我最近看到一条评论如下:

多维数组需要大量时间进行数组访问。为了提高它们的缓存和访问速度,建议保持索引从小到大,即声明 rmq 数组,如 rmq[11][11][1002][1002] 而不是 rmq[1002][1002][11][11]

我尝试了一个代码来测试它。在代码 1 中:

int pre_compute[18][100001];    //global variable

int main(){
    /*some precomputations on pre_compute array 
    of the order of size of the array*/

    /*Run 10^8 queries on pre_compute array,
    O(1) per query.*/
}

代码 2:

int pre_compute[100001][18];    //global variable

int main(){
    /*exact same precomputations on pre_compute array as done in Code 1 
    of the order of size of the array*/

    /*Run 10^8 queries on pre_compute array,
    O(1) per query.*/
}

除了数组的分布之外,这两个代码都是相同的。两个代码之间仍然存在很大的执行时间差异。第一个代码在我的 PC 上平均占用了 0.40 secs,而另一个代码平均占用了 1.42 secs

数组的两个实现之间的执行时间差异如此之大的可能原因是什么?

【问题讨论】:

  • @vu1p3n0x 后者几乎是完全的问题,并且描述了实际使用声明的数组的不方便省略的代码中发生的事情。干得好。
  • 下次请提供minimal reproducible example,如果您不同意重复回答您的问题,请在此处发布。
  • 此外,任何与性能相关的问题都应附有用于构建测试的命令行,更明确地说,用于构建程序的优化。这类问题出现的次数太多,发现发帖人正在测试未优化和/或“调试”的构建,结果毫无意义。

标签: c++ arrays performance multidimensional-array


【解决方案1】:

这正是行优先和列优先有序矩阵之间的区别。

区别在Wikipedia上解释:

按行优先顺序,数组行的连续元素在内存中是连续的;按列优先顺序,列的连续元素是连续的。

C 和 C++ 是行优先的,因此由于空间局部性,它们可以利用行缓存。这解释了加速的显着提高。

从技术上讲,如果您想节省大量时间,最好将多维数组表示为一维数组。 :)

【讨论】:

  • 由于 Fortran 是 Column Major 顺序,在不处理问题的情况下移植 Fortran->C 可能会导致性能问题。
  • @EvilTeach 是的 - 绝对的噩梦。
  • 如果您的访问模式是行主要的,那么将多维数组表示为一维数组不会真正改变任何内容或节省任何时间。如果您将访问模式从列主要更改为行主要,或者您使用列主要访问并使用带有索引计算的一维表示来影响列主要存储顺序,则会提高性能。
猜你喜欢
  • 1970-01-01
  • 2019-05-23
  • 2020-05-11
  • 2021-06-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-27
相关资源
最近更新 更多