我有一个程序要将同一个容器矩阵中的两个子矩阵相乘。我试图通过使用OpenMP API进行并行化来提高性能。下面是我使用的乘法算法。
#pragma omp parallel for
for(size_t i = 0; i < matrixA.m_edgeSize; i++) {
for(size_t k = 0; k < matrixA.m_edgeSize; k++) {
for(size_t j = 0; j < matrixA.m_edgeSize; j++) {
resultMatrix(i, j) += matrixA(i, k) * matrixB(k, j);
}
}
}
该算法对两个输入子矩阵的元素进行逐行访问,以提高缓存的空间局部性。
还有什么其他OpenMP指令可以用来从这个简单的算法中获得更好的性能?有没有其他指令可以用来优化两个子矩阵的重叠区域上的操作?
- 您可以假设所有子矩阵的大小相同,并且都是方形的。生成的子矩阵位于另一个容器矩阵中。*
2条答案
按热度按时间wvt8vs2t1#
对于矩阵-矩阵乘积,
i,j,k
索引的任何排列都可以顺序地计算正确的结果。并行计算就不是这样了。在原始代码中,k
迭代不会写入唯一的位置,因此您不能只折叠外部两个循环。执行k,j
交换,然后它 * 是 * 允许的。当然,OpenMP可以让你从一个内核的5%效率提升到所有内核的5%。你真的想阻止循环。但这要困难得多。请参阅后藤和货车de Geijn的论文。
kzmpq1sx2#
我添加了一些与主矩阵相关的内容。您是否使用此代码将两个更大的矩阵相乘?然后其中一个子矩阵在不同的迭代之间重用,并可能受益于CPU缓存。例如,如果一个矩阵有4个子矩阵,则每个子矩阵使用两次,以获得结果矩阵的值。
为了从缓存中获得最大的好处,重用的数据应该保存在同一个线程(内核)的缓存中。要做到这一点,也许最好将工作分配级别移动到选择两个子矩阵的位置。
所以,事情是这样的:
可以更快地工作,因为整个数据总是停留在同一线程(核心)中。