我目前正在试验使用GPU的OpenCL代码的性能,并在CPU上使用C++。我编写了计算总和z = x + y的程序,其中z,x和y是GPU和CPU的二维数组(矩阵)。在测试这些程序之后,我发现由于GPU和CPU之间的PCI总线中的数据传输缓慢,所以CPU在计算这一总和方面比GPU更高效。现在我想确定为了使GPU比CPU更有效,还需要多少钱。我打算通过增加z = x + y到z = x + y + y + y + y + ...等来做到这一点。在GPU和CPU上添加2D阵列的性能
仅通过增加此特定问题的总和数量,是否有可能使GPU的使用效率高于CPU?
正如仅供参考:我使用的是nVIDIA GeForce GT 640图形卡和i5 Intel核心CPU。
任何帮助将不胜感激。
编辑:
下面我附着在CPU上我的代码:
int main(int argc, const char * argv[])
{
//This value determines the size of the nxn (square array)
int n = 1000;
//Allocating the memory for the nxn arrays of floats.
float **x = (float**)malloc(sizeof(float*)*n);
float **y = (float**)malloc(sizeof(float*)*n);
float **z = (float**)malloc(sizeof(float*)*n);
//Initializing the arrays.
for(int i = 0; i<n; i++){
x[i] = (float*)malloc(sizeof(float)*n);
y[i] = (float*)malloc(sizeof(float)*n);
z[i] = (float*)malloc(sizeof(float)*n);
for(int j = 0; j<n; j++){
x[i][j] = i+j;
y[i][j] = i+j;
}
}
for(int i = 0; i<n; i++){
for(int j = 0; j<n; j++){
z[i][j] = x[i][j] + y[i][j];
for(int k = 0; k < 100; k++){
z[i][j] += y[i][j];
}
}
}
return 0;
}
这里是C++使用OpenCL的:(用于复制数据,并执行对GPU内核)
int n = 1000;
for(int i = 0; i<n; i++)
{
//Writing the data from the host to the device
err = clEnqueueWriteBuffer(queue, d_xx, CL_TRUE, 0, sizeof(float)*n, h_xx[i], 0, NULL, NULL);
if(err != CL_SUCCESS){
std::cout << "Error: Could not write to buffer d_xx" << std::endl;
exit(1);
}
err = clEnqueueWriteBuffer(queue, d_yy, CL_TRUE, 0, sizeof(float)*n, h_yy[i], 0, NULL, NULL);
if(err != CL_SUCCESS){
std::cout << "Error: Could not write to buffer d_yy" << std::endl;
exit(1);
}
//Setting the Kernel Arguments
err = clSetKernelArg(kernel, 0, sizeof(cl_mem), &d_xx);
if(err != CL_SUCCESS){
std::cout << "Error: Could not set kernel argument h_xx." << std::endl;
exit(1);
}
err = clSetKernelArg(kernel, 1, sizeof(cl_mem), &d_yy);
if(err != CL_SUCCESS){
std::cout << "Error: Could not set kernel argument h_yy." << std::endl;
exit(1);
}
err = clSetKernelArg(kernel, 2, sizeof(cl_mem), &d_zz);
if(err != CL_SUCCESS){
std::cout << "Error: Could not set kernel argument h_zz." << std::endl;
}
work_units_per_kernel = n;
//Executing the Kernel
err = clEnqueueNDRangeKernel(queue, kernel, 1, NULL, &work_units_per_kernel, NULL, 0, NULL, NULL);
if(err != CL_SUCCESS){
std::cout << "Error: Could not execute kernel." << std::endl;
exit(1);
}
//Reading the Data from the Kernel
err = clEnqueueReadBuffer(queue, d_zz, CL_TRUE, 0, n*(sizeof(float)), h_zz[i], 0, NULL, NULL);
if(err != CL_SUCCESS){
std::cout << "Error: Could not read data from kernel." << std::endl;
exit(1);
}
}
而且最后在GPU上执行的内核代码:
__kernel void arraysum(__global const float *d_aa, __global const float *d_bb, __global float *d_cc)
{
int i = get_global_id(0);
d_cc[i] = d_aa[i] + d_bb[i];
for(int j = 0; j < 100; j++){
d_cc[i] += d_bb[i];
}
}
你为什么不在这里发布你的代码? GPU如果与你并列,就会获胜。 GPU也可能具有更快的内存。你的程序是否并行?因为一个cpu线程会比一个GPU“线程”执行得更好。 – SigTerm
@SigTerm感谢您的回复。我附加了一些我的代码片段。我希望他们帮助澄清我是否在我的程序中并行化。 – user2736519
在我看来,这是一个很少计算的经典案例,整个操作都是内存绑定的,所以除非您可以对GPU上的数据做更多的事情,否则总线速度将比GPU本身获得的更多。 –