6

我在 C 中创建了以下结构“数据”

typedef struct data
{
  double *dattr;                           
  int d_id;                                
  int bestCent;                            
}Data;

'dattr' 是上述结构中保持动态的数组。假设我必须创建 10 个上述结构的对象。IE

dataNode = (Data *)malloc (sizeof(Data) * 10);

对于这个结构的每个对象,我必须使用 C 为数组“dattr”重新分配内存:

for(i=0; i<10; i++)
   dataNode[i].dattr = (double *)malloc(sizeof(double) * 3);

应该如何在 OpenCL 中实现相同的功能?为结构对象分配内存后,如何为数组“dattr”分配内存?

4

2 回答 2

6

OpenCL 设备(例如,GPU)中的内存分配必须在主机线程中使用clCreateBuffer(或clCreateImage2D / 3D,如果您希望使用纹理内存)执行。这些函数允许您自动将主机数据(例如使用 malloc 创建)复制到设备,但我通常更喜欢显式使用clEnqueueWriteBuffer / clEnqueueMapBuffer(或clEnqueueWriteImage / clEnqueueMapImage,如果使用纹理内存),以便我可以分析数据传输。这是一个例子:

#define DATA_SIZE 1000

typedef struct data {
    cl_uint id;
    cl_uint x;
    cl_uint y;
} Data;

...

// Allocate data array in host
size_t dataSizeInBytes = DATA_SIZE * sizeof(Data);
DATA * dataArrayHost = (DATA *) malloc(dataSizeInBytes);

// Initialize data
...

// Create data array in device
cl_mem dataArrayDevice = clCreateBuffer(context, CL_MEM_READ_ONLY, dataSizeInBytes, NULL, &status );

// Copy data array to device
status = clEnqueueWriteBuffer(queue, dataArrayDevice, CL_TRUE, 0, dataSizeInBytes, &dataArrayHost, 0, NULL, NULL );

// Make sure to pass dataArrayDevice as kernel parameter
// Run kernel
...

您需要考虑的是,在执行 OpenCL 内核之前,您需要了解它的内存需求。因此,如果在内核执行之前(即在主机中)执行内存分配,则可以是动态的。没有什么能阻止您多次调用内核,并且在每次调用内核时都调整(分配)内核内存需求。

考虑到这一点,我建议您重新考虑解决问题的方式。首先,使用结构数组比使用数组结构更简单(但不一定更有效)(在这种情况下,数组无论如何都必须具有固定大小)。

这只是为了让您了解 OpenCL 的工作原理。看看Khronos OpenCL 资源页面,它有很多 OpenCL 教程和示例,还有Khronos OpenCL 页面,它有官方 OpenCL 参考、手册页和快速参考卡。

于 2013-01-11T01:45:28.443 回答
2

正如 Faken 所建议的,如果您关心动态内存分配并且您渴望稍微更改算法,这里有一些提示:

以下代码动态分配本地内存空间并将其作为第 8 个参数传递给 OpenCL 内核:

  int N; //Number_of_data_points, which will keep on changing as per your requirement  
   size_t localMemSize = ( N* sizeof(int));      
 ...   
 // Dynamically allocate local memory (allocated per workgroup)
 clSetKernelArg(kernel, 8, localMemSize, NULL);
于 2013-01-11T11:49:31.873 回答