Memory management CUDA内核调用参数超过256字节的想法
我有几个结构的总和超过了内核调用中允许作为参数传递的256字节大小 这两个结构都已分配并复制到设备全局内存 1)我如何在这些结构的同一内核中使用,而不作为参数传递 更多细节。另外,这些结构可以作为参数传递。例如,在不同的内核中。但是:Memory management CUDA内核调用参数超过256字节的想法,memory-management,parameters,cuda,gpgpu,Memory Management,Parameters,Cuda,Gpgpu,我有几个结构的总和超过了内核调用中允许作为参数传递的256字节大小 这两个结构都已分配并复制到设备全局内存 1)我如何在这些结构的同一内核中使用,而不作为参数传递 更多细节。另外,这些结构可以作为参数传递。例如,在不同的内核中。但是: 2)如何在同一内核中使用这两种结构?如果您的数据结构已经在全局内存中,那么您只需传入一个指针作为内核参数 另一方面,对于计算能力为2.x或更高的设备,内核参数的限制为4KB: 全局功能参数被传递到设备: 通过共享内存,在计算能力为1.x的设备上限制为256字节
2)如何在同一内核中使用这两种结构?如果您的数据结构已经在全局内存中,那么您只需传入一个指针作为内核参数 另一方面,对于计算能力为2.x或更高的设备,内核参数的限制为4KB: 全局功能参数被传递到设备:
- 通过共享内存,在计算能力为1.x的设备上限制为256字节
- 通过恒定内存,在计算能力为2.x及更高的设备上限制为4KB
(c.f.)正如罗伯特·克罗维拉在评论中所建议的那样,您应该能够传递一个指向这些区域的指针。 我在opencl中也遇到过类似的问题。。 这就是我实现结构的方式: (我的内核和主机函数在opencl中,语法可能是您的问题..但上下文是相同的。!) 以下两个是在我的“Mapper.c”-->主机函数中定义的
typedef struct data
{
double dattr[10];
int d_id;
int bestCent;
}Data;
typedef struct cent
{
double cattr[5];
int c_id;
}Cent;
Data *dataNode;
Cent *centNode;
在设备的全局内存上分配内存后,我传输了数据。
我必须在另一个内核函数中重新定义结构定义,如下所示:
mapper.cl:
#pragma OPENCL EXTENSION cl_khr_fp64 : enable
typedef struct data
{
double dattr[10];
int d_id;
int bestCent;
}Data;
typedef struct cent
{
double cattr[5];
int c_id;
}Cent;
__kernel void mapper(__global int *keyMobj, __global int *valueMobj,__global Data *dataMobj,__global Cent *centMobj)
{
int i= get_global_id(0);
int j,k,color=0;
double dmin=1000000.0, dx;
for(j=0; j<2; j++) //here 2 is number of centroids considered
{
dx = 0.0;
for(k=0; k<2; k++)
{
dx+= ((centMobj[j].cattr[k])-(dataMobj[i].dattr[k])) * ((centMobj[j].cattr[k])-(dataMobj[i].dattr[k]));
}
if(dx<dmin)
{ color = j;
dmin = dx;
}
}
keyMobj[i] = color;
valueMobj[i] = dataMobj[i].d_id;
}
上面的代码行属于主机端函数(mapper.c),它创建了内核函数(mapper.cl)…接下来的4行(clSetKernelArg..)将参数传递给内核函数。如果结构已经分配并复制到设备全局内存中,您应该能够传递指向这些区域的指针。没有必要也没有理由按值传递这些值。@RobertCrovella谢谢。我不确定我是否可以从CPU端内核调用中指出,以及如何指出这些区域。计算能力1.3有很多限制!谢谢我明白了。我将尝试在CUDA代码中实现,回来时会有更多的输入,可能还会有更多的问题。谢谢。我在文件中读到了这一部分。目前,我的计算能力为1.3(特斯拉C1060)。希望很快升级(希望在我完成论文之前)。
kernel = clCreateKernel(program, "mapper", &ret);
ret = clSetKernelArg(kernel, 0, sizeof(cl_mem), (void *)&keyMobj);
ret = clSetKernelArg(kernel, 1, sizeof(cl_mem), (void *)&valueMobj);
ret = clSetKernelArg(kernel, 2, sizeof(cl_mem), (void *)&dataMobj);
ret = clSetKernelArg(kernel, 3, sizeof(cl_mem), (void *)¢Mobj);