CUDA是基于nvidia的显卡SDK一门并行编程技术。做矩阵相乘自然是“得心应手”。
设A为 的矩阵,B为 的矩阵,那么称 的矩阵C为矩阵A与B的乘积,记作 。
C/CPP串行实现代码:
int Matrix::MatMulti(Mat &MatA, Mat &MatB, Mat &MatC){
if(MatA.col!=MatB.row)
return 1;
MatCreat(MatA.row, MatB.col, MatC);
int i,j,k;
for(i=0; i<MatC.row; i++) {
for(j=0; j<MatC.col; j++) {
for(MatC.mat[i][j]=k=0; k<MatA.col; k++) {
MatC.mat[i][j] += MatA.mat[i][k] * MatB.mat[k][j];
}
}
}
return 0;
}
但是计算公式的数据间无依赖,可以实现并行。
核函数:
__global__ void cudaMatMulti(CudaMat *cudaMatA, CudaMat *cudaMatB, CudaMat *cudaMatC){
unsigned int col = blockIdx.x*blockDim.x + threadIdx.x;
unsigned int row = blockIdx.y*blockDim.y + threadIdx.y;
if(col>= cudaMatC->col || row>=cudaMatC->row) return;
int temp = 0;
for(int i = 0; i<cudaMatC->col; i++)
temp += cudaMatA->mat[i+row*cudaMatA->col] * cudaMatB->mat[col+i*cudaMatB->col];
cudaMatC->mat[col+row*cudaMatC->col] = temp;
}
如果要使用多核CPU计算,则可以加入openMP技术,轻松将C代码粗粒度并行。
#ifdef _OPENMP
#include <omp.h>
#endif
int Matrix::MatMulti(Mat &MatA, Mat &MatB, Mat &MatC){
if(MatA.col!=MatB.row)
return 1;
MatCreat(MatA.row, MatB.col, MatC);
#ifdef _OPENMP
#pragma omp parallel for schedule(dynamic, 1) num_threads(8)
#endif
for(int i=0; i<MatC.row; i++) {
#ifdef _OPENMP
#pragma omp parallel for schedule(dynamic, 1) num_threads(8)
#endif
for(int j=0; j<MatC.col; j++) {
int k;
for(MatC.mat[i][j]=0 , k=0; k<MatA.col; k++) {
MatC.mat[i][j] += MatA.mat[i][k] * MatB.mat[k][j];
}
}
}
return 0;
}
但是记得在编译的时候在cxx_flag加上:
-fopenmp
才能支持openMP。