【问题标题】:Time taken:Row major sum Column major sum所用时间:行主要总和 列主要总和
【发布时间】:2013-11-09 04:53:26
【问题描述】:

我遇到了这个问题,我有点困惑。给出了两个代码,询问哪个代码需要更多时间,或者两者是否需要相同时间。代码是:

void sumCal(int n,int a[][]){
   int sum=0;
   for(int i=0;i<n;i++){
      for(int j=0;j<n;j++){
         sum=sum+a[i][j];
      }
   }
}

void sumCal(int n,int a[][]){
   int sum=0;
   for(int i=0;i<n;i++){
      for(int j=0;j<n;j++){
         sum=sum+a[j][i];
      }
   }
}

据我所知,这取决于内存布局,内存是按行为主还是按列为主。这是正确的答案吗?

【问题讨论】:

    标签: c


    【解决方案1】:

    一个主要问题确实是矩阵是以行优先格式还是列优先格式布局。这是由 C 标准定义的;这不是编译器编写者的事情。另一个主要问题是数组的大小。如果它小到足以放入高速缓存,那么使用哪种机制并不重要,但如果它太大而无法放入高速缓存,那么一种机制比另一种机制快得多。

    它是什么?好吧,在 Wikipedia 上快速搜索 Row-major Order 表明 C 使用行优先顺序。

    【讨论】:

      【解决方案2】:

      我实际上并不确定代码是否会首先编译,因为维度需要包含在第一个维度之后的每个维度的数组的函数参数声明中。

      无论如何,C 是行主要的(意味着行中的元素连续存储在内存中,实际上对于 C 中的多维数组,整个数组是连续的),所以第一个选项可能更快,因为内部循环遍历通过遍历列来行。

      最后,您需要知道阵列有多大,以及您使用的 CPU 上的 L1 缓存有多大。如果阵列可以容纳在 L1 缓存中,那么这两个选项应该以相同的速度运行,因为在使用完之前不会弹出任何缓存行。

      【讨论】:

      • +1:你是对的;除了(可能)第一个之外,如果没有每个数组维度的维度,代码将无法编译。在 C99 中,您可以编写:void sumByCols(int n, int a[n][n]) { ... }void sumByRows(int n, int a[n][n]) { ... }。在较旧的 C 中,您要么必须修复第二维(因此也是第一个,使参数 n 有点毫无意义),或者您必须创建一个更复杂的结构(指向 @ 的指针数组987654324@),或者你会传递一个int * 并在函数体中进行下标计算。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-06-24
      • 1970-01-01
      • 2021-09-21
      • 2012-08-15
      相关资源
      最近更新 更多