CUDA内核和内存访问(一个内核不完全执行,下一个内核不启动)

时间:2012-09-12 21:59:10

标签: memory cuda

我在这里遇到麻烦。我启动了两个内核,检查一些值是否是预期值(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)。重量数组也是如此,蚂蚁* sizeof(浮点数)。所以他们不会出界。

这个之后的内核在开头就有一个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最大值或检查我可以将这个值放得多高。

1 个答案:

答案 0 :(得分:2)

仅当条件在块的所有线程上进行相同计算时,才允许在条件代码中使用

__syncthreads()

在你的情况下,条件会遇到竞争条件并且是不确定的,所以它很可能会评估不同线程的不同结果。

printf()输出仅在内核成功完成后显示。在这种情况下,由于上述问题,它不会出现,因此输出永远不会显示出来。你可以通过测试所有CUDA函数调用返回代码来解决这个问题。