0

我试图找出一个很好的循环展开来将两个矩阵相乘。

例如,如果我们想对 NxN 矩阵求和:

void SumMatrix(int *M, int n, int *result) 
{ 
  int  i,j; 

  *result = 0; 
  for (i=0; i<n; i++) 
    for (j=0; j<n; j++) 
      *result += M[j][i]; 
}

我们可以完成这个 :

void SumMatrix(int *M, int n, int *result) 
{ 
    int  i; 
    int  size = n*n; 
    int  last = size%8; 
    int  acc1 = 0; 
    int  acc2 = 0; 
    int  *pEnd = M+size-last; 

    for (; M<pEnd; M+=8) 
    { 
      acc1 += (*M + *(M+1)) + (*(M+2) + *(M+3));
      acc2 += (*(M+4) + *(M+5)) + (*(M+6) + *(M+7));
    } 

    /* adding the last entries */ 
    while (last--)  
        acc1 += *(M++); 

    *result = acc1+acc2;        
}

但我试图找到一种(好的)方法来乘以 2 个矩阵,但目前没有找到。

备注: 这 不是 家庭 作业 , 我 今天 有 考试 , 刚刚 想到 这个 问题 , 我 觉得 这 可能 是 一个 很好 的 考试 题 , 不是 吗 ?

我会很感激任何帮助

问候

罗恩

4

2 回答 2

2

大多数编译器都会为您展开(您可能需要打开一个标志,或将其设置为优化级别 - 我相信-funroll-loops它适用于 gcc)。

此外,对于您的问题,它是 2D 矩阵这一事实并不重要,因为您正在将所有数字相加。如果您仅限于单个进程/线程,则按顺序将数字相加将是最快的,因为这具有最佳的缓存性能。您可能会从 SSE 或向量指令中获得一些好处;同样,今天的编译器可以为您解决如此简单的问题。

于 2012-04-19T07:40:09.457 回答
0

看看 ATLAS 项目有多复杂,它提供了 BLAS 库的优化版本(主要基于矩阵乘法)。它不仅应该考虑线程级并行性,还应该考虑内存层次结构(不仅是展开,还应该考虑缓存平铺和寄存器平铺、软件流水线等)。它通常由手写或由“自动调谐器”优化,如 ATLAS。如果您想解开线程级并行性,您最好使用“平铺算法”并在线程之间传播生成的平铺计算。

于 2012-04-27T17:08:30.720 回答