OpenMP并行化(Block Matrix Mult)

我正在尝试实现块矩阵乘法并使其更加并行化。

这是我的代码:

int i,j,jj,k,kk; float sum; int en = 4 * (2048/4); #pragma omp parallel for collapse(2) for(i=0;i<2048;i++) { for(j=0;j<2048;j++) { C[i][j]=0; } } for (kk=0;kk<en;kk+=4) { for(jj=0;jj<en;jj+=4) { for(i=0;i<2048;i++) { for(j=jj;j<jj+4;j++) { sum = C[i][j]; for(k=kk;k<kk+4;k++) { sum+=A[i][k]*B[k][j]; } C[i][j] = sum; } } } } 

我一直在玩OpenMP,但是在找出在最短的时间内完成这项工作的最佳方法仍然没有运气。

从矩阵乘法中获得良好的性能是一项重要工作。 由于“最好的代码是我不必编写的代码”,因此更好地利用您的时间将是了解如何使用BLAS库。

如果您使用的是X86处理器,则可免费获得英特尔数学核心库(MKL),并包括优化的并行化矩阵乘法运算。 https://software.intel.com/en-us/articles/free-mkl

(FWIW,我为英特尔工作,但没有在MKL工作:-))

我最近又开始研究密集矩阵乘法(GEMM)。 事实certificate,Clang编译器非常擅长优化GEMM,而不需要任何内在函数(GCC仍然需要内在函数)。 以下代码获得了我的四核/八硬件线程Skylake系统的峰值FLOPS的60%。 它使用块矩阵乘法。

超线程提供了更差的性能,因此您确保只使用等于内核数量的线程并绑定线程以防止线程迁移。

 export OMP_PROC_BIND=true export OMP_NUM_THREADS=4 

然后像这样编译

 clang -Ofast -march=native -fopenmp -Wall gemm_so.c 

代码

 #include  #include  #include  #include  #include  #define SM 80 typedef __attribute((aligned(64))) float * restrict fast_float; static void reorder2(fast_float a, fast_float b, int n) { for(int i=0; i *(double*)y; } double median(double *x, int n) { qsort(x, n, sizeof(double), doublecmp); return 0.5f*(x[n/2] + x[(n-1)/2]); } int main(void) { int cores = 4; double frequency = 3.1; // i7-6700HQ turbo 4 cores double peak = 32*cores*frequency; int n = SM*10*2; int mem = sizeof(float) * n * n; float *a = _mm_malloc(mem, 64); float *b = _mm_malloc(mem, 64); float *c = _mm_malloc(mem, 64); memset(a, 1, mem), memset(b, 1, mem); printf("%dx%d matrix\n", n, n); printf("memory of matrices: %.2f MB\n", 3.0*mem*1E-6); printf("peak SP GFLOPS %.2f\n", peak); puts(""); while(1) { int r = 10; double times[r]; for(int j=0; j 

这对于无限循环的每次迭代进行GEMM 10次,并将FLOPS的低,中和高比率打印到peak_FLOPS,最后打印FLOPS中值。

您需要调整以下行

 int cores = 4; double frequency = 3.1; // i7-6700HQ turbo 4 cores double peak = 32*cores*frequency; 

到物理核心的数量,所有核心的频率(如果启用了turbo),以及每个核心的浮动指针操作数量,Core2-Ivy Bridge为16 ,Haswell-Kaby Lake为32 ,Xeon Phi Knights为64降落。

使用NUMA系统时,此代码的效率可能较低。 它与Knight Landing的表现差不多(我刚开始研究这个问题)。