我创建了一个简单的OpenCL程序,它使用朴素矩阵乘法(具有O(n ^ 3)复杂度的矩阵乘法)乘以两个NxN矩阵。每个矩阵的每个值都是单精度32位浮点。该程序使用Windows 10 x64上的visual studio 2015进行编译。
N = 2048且使用intel OpenCL平台,经过的时间如下:
编辑:澄清一下,上面的CPU结果是使用英特尔的OpenCL CPU实现的。在常规的C ++串行CPU实现上,花了82秒。
在同一硬件上使用Nvidia OpenCL平台,结果差异不大:
以下是调用OpenCL的C ++代码:
//create kernel
cl_kernel krnl = clCreateKernel(program, "matmult", NULL);
//create buffer (for source matrices, read only)
cl_mem srcBuff = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, sizeof(float)*size*size, src, NULL);
cl_mem dstBuff = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, sizeof(float)*size*size, dst, NULL);
//buffer for result
float* res = (float*)malloc(sizeof(float)*size*size);
cl_mem resBuff = clCreateBuffer(context, CL_MEM_WRITE_ONLY, sizeof(float)*size*size, NULL, NULL);
//set kernel args
clSetKernelArg(krnl, 0, sizeof(cl_mem), &srcBuff);
clSetKernelArg(krnl, 1, sizeof(cl_mem), &dstBuff);
clSetKernelArg(krnl, 2, sizeof(cl_mem), &resBuff);
clSetKernelArg(krnl, 3, sizeof(int), &size);
//run
size_t dimSizes[] = { size,size };
clEnqueueNDRangeKernel(commandQueue, krnl, 2, NULL, dimSizes, NULL, NULL, NULL, NULL);
clEnqueueReadBuffer(commandQueue, resBuff, CL_TRUE, 0, sizeof(float)*size*size, res, 0, NULL, NULL);
return res;
这是OpenCL内核函数:
__kernel void matmult(__global const float* src, __global const float* dst,
__global float* ret, const int n) {
int y=get_global_id(0);
int x=get_global_id(1);
float sum=0;
for(int i=0;i<n;i++){
sum+=src[y*n+i] * dst[i*n+x];
}
ret[y*n+x]=sum;
}
答案 0 :(得分:2)
您需要付出更多努力才能让它在GPU上运行得更快。使用本地内存,平铺等
有很多关于这方面的文献。例如,这是一步一步的教程:Tutorial: OpenCL SGEMM tuning for Kepler。