打开global_work_size误解

时间:2014-12-08 08:22:32

标签: opencl

我正在尝试理解一个简单的OpenCL示例,它是矢量加法。内核如下:

__kernel void addVec(__global double* a, __global double* b, __global double* c)
{
  size_t id = get_global_id(0);
  c[id] = a[id] + b[id];
}

例如,我的输入数组的大小各为100万个元素。

在我的宿主程序中,我将global_work_size设置为矢量输入数组的大小(100万)。

但是当我将它设置为较小的值(例如1000)时,它也适用于此内核!

我不明白为什么global_work_size可能比问题维度小,而且OpenCL程序仍会计算输入数组的每个元素。

有人可以澄清这个吗?

编辑:这是我复制数据的代码:

size_t arraySize = 1000000;
const size_t global_work_size[1] = {512};

double *host_a = malloc(arraySize*sizeof(double));
double *host_b = malloc(arraySize*sizeof(double));
double *host_c = calloc(arraySize, sizeof(double));

...

// Create the input and output arrays in device memory for our calculation
device_a = clCreateBuffer(context, CL_MEM_READ_ONLY, arraySize*sizeof(double), NULL, NULL);
device_b = clCreateBuffer(context, CL_MEM_READ_ONLY, arraySize*sizeof(double), NULL, NULL);
device_c = clCreateBuffer(context, CL_MEM_WRITE_ONLY, arraySize*sizeof(double), NULL, NULL);

...

// Copy data set into the input array in device memory. [host --> device]
status = clEnqueueWriteBuffer(command_queue, device_a, CL_TRUE, 0, arraySize*sizeof(double), host_a, 0, NULL, NULL);
status |= clEnqueueWriteBuffer(command_queue, device_b, CL_TRUE, 0, arraySize*sizeof(double), host_b, 0, NULL, NULL);

...

// Copy-back the results from the device [host <-- device]
clEnqueueReadBuffer(command_queue, device_c, CL_TRUE, 0, arraySize*sizeof(double), host_c, 0, NULL, NULL );

...
printf("checking result validity ...\n");
for (size_t i=0; i<arraySize; ++i)
  if(host_c[i] - 1 > 1e-6) // the array is supposed to be 1 everywhere
  {
    printf("*** ERROR! Invalid results ! host_c[%zi]=%.9lf\n", i, host_c[i]);
    break;
  }

由于

1 个答案:

答案 0 :(得分:1)

您的测试功能看起来不太好,任何value < 1都会满足,它应该是这样的:

for (size_t i=0; i<arraySize; ++i){
  cl_double val = host_c[i] - 1; // the array is supposed to be 1 everywhere
  if((val > 1e-6) || (val < -1e-6)) 
  {
    printf("*** ERROR! Invalid results ! host_c[%zi]=%.9lf\n", i, host_c[i]);
    break;
  }
}

GPU中未初始化的值可能为0,因此符合您的条件。

此外,请记住,如果您使用完整大小运行程序一次,连续读取仍将保留正确处理的数据(即使您再次关闭并打开应用程序)。由于在创建/销毁缓冲区后未清除GPU内存。