CUDA 数组的使用

我想在CUDA 的volume rendering 例程上做一些改动,添加了两个函数
global void
data_init(uchar4* g_volume,uchar4* g_volumed,int xdim,int ydim,int zdim)//初始化一些数据
{
const int tid = threadIdx.x;
long i,j;
j=1;
for (i=0;i<xdimydim;i++)
{
(g_volumed+j
xdimydim+i)->x=255;
(g_volumed+j
xdimydim+i)->y=255;
(g_volumed+j
xdimydim+i)->z=255;
(g_volumed+j
xdim*ydim+i)->w=255;
}
g_xdim=xdim;
g_ydim=ydim;
g_zdim=zdim;
}

extern “C”
void initCudaarray(uchar4 h_volume,int xdim,int ydim,int zdim)
{
uchar4 g_volume,g_volumed=0;
//checkCudaErrors(cudaMalloc((void
)&g_volume,xdim
ydimsizeof(uchar4)));
checkCudaErrors(cudaMalloc((void**)&g_volumed,xdim
ydimzdimsizeof(uchar4)));
printf(“totot %f\n”,(float)xdimydimzdimsizeof(uchar4));
checkCudaErrors(cudaMemset(g_volumed,0,xdim
ydimzdimsizeof(uchar4)));
//checkCudaErrors(cudaMemcpy(g_volume,h_volume,xdimydimsizeof(uchar4),cudaMemcpyHostToDevice));
data_init<<<1,1>>>((uchar4 *)0/g_volume/,g_volumed,xdim,ydim,zdim);
}

其中xdim是5000,ydim是2500,zdim是3 。 运行这个程序的时候,显卡会停止工作。经测试,是data_init函数中的那个循环的地方出问题了,如果循环的小一点,程序可以正常运行,如果按照程序中的xdim*ydim,就会出错。
很不理解为什么会出现这种情况,数组分配的有那么大,为什么访问会出错呢?我用的显卡是GTX580,显存足够那个数组了。 能否帮忙解答一下呢

楼主您好,

"CUDA Array"是有特殊含义的,您这只是普通的cudaMalloc出的普通数组。
下文将按您帖子内容的实际意义,而不是标题意思解释,请知悉。

楼主您缺乏基本的CUDA概念,CUDA不是上一个线程(您的<<<1,1>>>>)自动拆循环的神奇玩意,
而是需要您的主观能动性的。

您填充一个500025003的4B为元素的数组,您的正确写法应该是上500025003个线程的,而不是在一个线程内试图循环填充此数组。

请立刻修正这里。同时建议您阅读手册,理解基本概念。
(否则您的循环将会导致kernel超时。虽然可以通过修改TDR规避。但效率将极度低下)
(而此时正确的做法则是使用正确的线程规模,而不是一个线程黑上。已经在上文建议了)

感谢来访。

谢谢版主的回复。确实刚接触CUDA,有很多不懂的地方。我改这个程序的目的是,在一个500025003的数组中,在z=1的维度上赋值。<<<1,1>>>调用确实效率低下,但我觉得这应该不是出错的原因吧?另外能否请教一下在CUDA中,一、二、三维数组的使用,是不是有根本性的差别?

LZ您好:

请您重新阅读2#的倒数第三行(不算空白行)。

以及CUDA C中数组的使用,原则上和C/C++中是一样的。

感谢深夜来访,祝您好运~

感谢您的回复。我刚才试了一下,感觉是超时了。。。非常感谢您
另外还是数组那个问题,既然使用没有什么区别,那么为什么会有一维的用malloc ,二维的用 mallocpitch,三维的用cudaMalloc3DArray?这些的区别在什么地方?

LZ您好:

cudaMalloc3DArray是申请cuda Array的,cuda Array是封闭的数据结构,并不是一般意义上的数组。

cudaMalloc可以申请连续的缓冲区,您可以将此用作一维,二维或者三维的数组。

cudaMallocPitch在申请二维数组的时候保证对齐性以提高访存效率,会增加padding的空间。

大致如此,祝您好运~

恩,学习了,感谢您的深夜回复。