基本并行实现的讨论:
正如前面所讲的,矩阵相乘过程中,结果矩阵C中的每个元素都是可以独立计算的,即彼此之间并无依赖性。所以如果采用更多的处理器,将会显著地提高矩阵相乘的计算效率。
对于大小为n × n 的矩阵,加入我们有n个处理器,那么结果矩阵中的每一行,都可以用一个处理器来负责计算。此时,总共的并行计算步数为 O(n^2)。你可以理解为在串行实现的代码中,最外层的循环 for(i=0;i<n;i++) 被分别由n个处理器来并行的执行,而每个处理需要完成的任务仅仅是内部的两层循环。
如果采用n^2个处理器,那么就相当于结果矩阵中的每个元素都由一个处理器来负责计算。此时,总共的并行计算步数为 O(n)。你可以理解为在串行实现的代码中,最外面的两层循环 被分解到n^2个处理器来并行的执行,而每个处理需要完成的任务仅仅是内部的一层循环,即for(k=0;k<n;k++)。
更进一步,如果有n^3个处理器,那么即使最内层的循环for(k=0;k<n;k++)也有n个处理器在并行的负责。但是最终的求和运算,我们需要一个类似reduction的操作,因此最终的计算复杂度就是O(log n)。
当然,你一定会想到的是,实际中,通常并不可能有像矩阵元素那么多的处理器资源。这时我们该怎么做。对于一个大小为n × n 的大矩阵A,我们其实可以把它切分成s^2个子矩阵Ap,q,每个子矩阵的大小为 m × m,其中 m = n / s,即0 <= p, q < s。对于两个大矩阵A和B,现在我们有:
传统矩阵分块并行乘法的基本思路:
把大的矩阵划分成小的矩阵块,比如n=6,有4个处理器(p=4),则把A和B矩阵均划分成由3x3的矩阵快组成的2x2的矩阵,如图所示:
存储:
P1处理器存储A00,B00;P2处理器存储A01,B01;P3处理器存储A10,B10;P4处理器存储A11,B11;
计算:
4个处理器分别计算C00,C01,C10,C11,由于C00=A00xB00+A01xB10,而P1处理器中只有A00和B00,所以A01和B10就需要从其他线程中传递过来,最终完成C00的计算。
缺点:
最终每个线程中都存储一行A和一列B(矩阵块),如P1中存储有A00,A01和B00,B10。于是大大增加了存储量,存储量由O(n平方)—>O(n立方)
cannon算法的目标就是减少分块矩阵乘法的存储量
Cannon算法
下面是矩阵位移的一个示例,;
参考资料:
https://blog.csdn.net/baimafujinji/article/details/48751037
https://blog.csdn.net/u013720726/article/details/70667697