OpenCL中对GPU的处理
OpenCL中kernel之前,GPU已经将寄存器资源分配好(静态分配资源),如果定义的私有临时存储空间是动态的,那么GPU驱动在解析kernel代码时将无法判定如何分配、存放临时数组变量(因为有可能存在寄存器不够用的情况)以及其它临时变量。
OpenCL kernel程序的编写最好以C89/90标准为主。
OpenCL kernel程序中只能静态开辟空间,(例如 private/local/global int a[10])
在OpenCL kernel程序中动态分配空间会报错。
如果想使用动态分配内存的指针类型,可以在host端声明并通过kernel函数的形参传入。(对于local指针作为形参,host端对应clSetKernelArg时,只能在相应位置传入NULL,原因具体如下)
clSetKernelArg
cl_int clSetKernelArg ( | cl_kernel kernel, |
cl_uint arg_index, | |
size_t arg_size, | |
const void *arg_value) |
Parameters
arg_value
为指向数据的指针,该数据应该用作arg_index指定的参数的参数值。 arg_value指向的参数数据被复制,因此在clSetKernelArg返回后,应用程序可以重用arg_value指针。指定的参数值是将内核(clEnqueueNDRangeKernel和clEnqueueTask)排入队列的所有API调用所使用的值,直到通过调用clSetKernelArg为内核更改参数值。
如果参数是内存对象(缓冲区或图像),则arg_value条目将是指向相应缓冲区或图像对象的指针。必须使用与内核对象关联的上下文创建内存对象。如果参数是缓冲区对象,也可以指定NULL值,在这种情况下,NULL值将用作声明为内核中__global或__constant内存的指针的参数值。如果使用__local限定符声明参数,则arg_value条目必须为NULL。如果参数的类型为sampler_t,则arg_value条目必须是指向采样器对象的指针。
如果声明参数是带有__global或__constant限定符的内置或用户定义类型的指针,则指定为参数值的内存对象必须是缓冲区对象(或NULL)。如果使用__constant限定符声明参数,则内存对象的大小(以字节为单位)不能超过CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE,并且使用__constant限定符声明的参数数不能超过CL_DEVICE_MAX_CONSTANT_ARGS。
如果参数声明为image2d_t类型,则指定为参数值的内存对象必须是2D图像对象。如果声明参数为image3d_t类型,则指定为参数值的内存对象必须是3D图像对象。
对于所有其他内核参数,arg_value条目必须是指向要用作参数值的实际数据的指针。