2013-04-20 259 views
4

我想执行块矩阵乘法(将matirix分成多个sxs矩阵并乘以相应的块)。我已经按照Hennesy的体系结构书的示例代码编写了代码:块矩阵乘法

for(int jj=0;jj<=(n/s);jj += s){ 
      for(int kk=1;kk<=(n/s);kk += s){ 
        for(int i=1;i<=(n/s);i++){ 
          for(int j = jj; j<=((jj+s-1)>(n/s)?(n/s):(jj+s-1)); j++){ 
            temp = 0; 
            for(int k = kk; k<=((kk+s-1)>(n/s)?(n/s):(kk+s-1)); k++){ 
              temp += b[i][k]*a[k][j]; 
            } 
            c[j][i] += temp; 
          } 
        } 
      } 
    } 

这里,nxn是原始矩阵的大小。 a,b矩阵大小相同。我将a,b矩阵分成大小为sxs的块。在我的程序中,我已经给出了块大小为4.我把a,b的所有元素设置为5,常量和n = 1000。但是,我的结果中出现错误的值。我在这里做错了什么?从过去的2小时中吸取了这一点。如果可能的话,你们可以帮忙吗?在书中的参考码是这样的:

for (jj = 0; jj <= size; jj += N) { 
    for (kk = 1; kk <= size; kk += N) { 
     for (i = 1; i <= size; i++) { 
      for (j = jj; j <= findMin(jj+N-1, size); j++) { 
       temp = 0; 
       for (k = kk; k <= findMin(kk+N-1, size); k++) { 
        temp += B[i][k] * A[j][k]; 
       } 
       C[j][i] += temp; 
      } 
     } 
    } 
} 

在此,S = N和大小= N/S

+1

你能提炼成一个小示例代码用输入产生问题并解释你期望的答案是什么? – 2013-04-20 02:07:14

+0

投票结束为什么不是此代码工作。 – 2016-03-31 10:50:43

回答

4
for(int jj=0;jj<N;jj+= s){ 
     for(int kk=0;kk<N;kk+= s){ 
       for(int i=0;i<N;i++){ 
         for(int j = jj; j<((jj+s)>N?N:(jj+s)); j++){ 
           temp = 0; 
           for(int k = kk; k<((kk+s)>N?N:(kk+s)); k++){ 
             temp += a[i][k]*b[k][j]; 
           } 
           c[i][j] += temp; 
         } 
       } 
     } 
} 

AXB 大小是N

1

乍一看我很惊讶地看到0和1开始索引和< =用于循环终止测试。 Fortran或matlab代码的书籍有时会有1种索引,而c/C++使用0种索引。

您也可以分别实现和/或测试内部的两个for循环,因为它们将用于单块矩阵乘法。

我会保持findMin函数分开,而不是在循环测试中内联它。

2

错误在这一行。你有

temp += b[i][k]*a[k][j]; 

,你应该有

temp += b[i][k]*a[j][k]; 

代替。

这也将是更好,如果你可以把这块的功能,而不是这一行:

((jj+s-1)>(n/s)?(n/s):(jj+s-1)); 
+0

谢谢。我把它放在那里,因为多次调用函数不利于性能。并感谢您指出错误。 – 2013-04-20 03:53:24

+1

@JustinCarrey“多次调用函数对性能不好”这是不正确的。值的可读性首先,性能只有在明显的问题。 – Andrei 2013-04-20 18:40:48

+0

完全同意@Andrei。如果你真的担心你可以使用关键字“inline”。顺便说一句。在这种情况下,编译器会为你内联,所以你甚至不需要做任何事情。 – 2013-04-22 15:05:15