【发布时间】:2012-09-05 23:27:45
【问题描述】:
我在这里遇到了麻烦。我启动了两个内核,检查某个值是否是预期的值(memcpy 到主机),如果是我停止,如果不是我再次启动这两个内核。
第一个内核:
__global__ void aco_step(const KPDeviceData* data)
{
int obj = threadIdx.x;
int ant = blockIdx.x;
int id = threadIdx.x + blockIdx.x * blockDim.x;
*(data->added) = 1;
while(*(data->added) == 1)
{
*(data->added) = 0;
//check if obj fits
int fits = (data->obj_weights[obj] + data->weight[ant] <= data->max_weight);
fits = fits * !(getElement(data->selections, data->selections_pitch, ant, obj));
if(obj == 0)
printf("ant %d going..\n", ant);
__syncthreads();
...
代码在此之后继续。但是那个 printf 永远不会被打印出来,那个 syncthreads 只是为了调试目的。
“添加”变量是共享的,但由于共享内存是 PITA 并且通常会在代码中引发错误,所以我暂时将其删除。这个“添加”变量不是最聪明的做法,但它比替代方法更快,后者检查数组中的任何变量是否是主机上的某个值并决定是否继续迭代。
getElement,只是简单地用音高做矩阵内存计算以访问正确的位置并返回那里的元素:
int* el = (int*) ((char*)mat + row * pitch) + col;
return *el;
obj_weights 数组具有正确的大小,n*sizeof(int)。权重数组 ants*sizeof(float) 也是如此。所以它们并没有越界。
这个之后的内核在开始时有一个 printf,它也不会被打印,并且在 printf 之后它在设备内存上设置一个变量,并且在内核完成后将该内存复制到 CPU,当我在 CPU 代码中打印它时,它不是正确的值。所以我认为这个内核正在做一些非法的事情,第二个甚至没有启动。
我正在测试一些实例,当我启动 8 个块和 512 个线程时,它运行正常。 32 个块,512 个线程,OK。但是8块1024线程,这样一来,内核就不行了,32块1024线程也不行。
我做错了吗?内存访问?我是否启动了太多线程?
编辑:尝试删除“添加”变量和 while 循环,因此它应该只执行一次。仍然不起作用,没有任何内容被打印,即使 printf 就在三个初始行之后并且下一个内核也没有打印任何内容。
编辑:另一件事,我使用的是 GTX 570,因此根据http://en.wikipedia.org/wiki/CUDA,“每个块的最大线程数”为 1024。也许我会坚持最大 512 或检查我能把这个值放多高。
【问题讨论】: