矩阵产品效率比较

时间:2018-08-12 23:46:25

标签: c matrix optimization matrix-multiplication

当我使用不同的方法进行矩阵乘法和测量执行时间时,我对这些结果提出了一些疑问。

矩阵:float A[N][N], B[N][N], C[N][N];

按矩阵读取顺序:

  • IJK

    for (i=0; i<N; i++)    
      for (j=0; j<N; j++)
        for (k=0; k<N; k++) 
          C[i][j] = C[i][j] + A[i][k] * B[k][j];
    
  • JKI

    for (j=0; j<N; j++)
      for (k=0; k<N; k++) 
        for (i=0; i<N; i++) 
          C[i][j] = C[i][j] + A[i][k] * B[k][j];
    
  • KIJ

    for (k=0; k<N; k++) 
      for (i=0; i<N; i++) 
        for (j=0; j<N; j++)
          C[i][j] = C[i][j] + A[i][k] * B[k][j];
    

使用辅助:

  • IJK

    for (i=0; i<N; i++) {
      for (j=0; j<N; j++) {
        aux = C[i][j];
        for (k=0; k<N; k++) {
          aux = aux + A[i][k] * B[k][j];
        }
        C[i][j] = aux;
      }
    }
    
  • JKI

    for (j=0; j<N; j++) {
      for (k=0; k<N; k++) {
        aux = B[k][j];
        for (i=0; i<N; i++) {
          C[i][j] = C[i][j] + A[i][k] * aux;
        }
      }
    }
    
  • KIJ

    for (k=0; k<N; k++) {
      for (i=0; i<N; i++) {
        aux = A[i][k];
        for (j=0; j<N; j++) {
          C[i][j] = C[i][j] + aux * B[k][j];
        }
      }
    }
    

我的执行时间:

Results

我头上发生了什么

更突出的是“ JKI”超过大小512所花费的时间增加。我猜这是因为矩阵无法容纳超过该大小的缓存,而“ JKI”的问题在于所有访问都是从上到下bot并从左到右,而不是从左到右,从上到下是bot,就像“ IJK”中的C和A以及“ KIJ”中的C和B一样。如果每当在高速缓存中加载一个块时发生另一种情况,那么下次访问就会被命中,这就是为什么'IJK'和'KIJ'更快的原因。如果我错了请纠正我。

我无法克服的是为什么“ KIJ”比“ IJK”更快。应该不一样吗? [q1]

为什么在'JKI'中使用辅助字符,据说减少对内存的访问与普通的'JKI'具有相同的执行时间? [q2]

最后,为什么用'-O2'标志在'KIJ'中大大减少了执行时间,而在'JKI'中却几乎没有改变? [q3] 我也想知道真正的做-O2来优化。

最终结论:从这6个示例中可以得出带有辅助词的“ KIJ”。我想知道是否有更快的算法。 [q4]

0 个答案:

没有答案