有时候不会调用CUDA回调

时间:2015-11-19 11:28:47

标签: c cuda callback

我正在写一些CUDA代码。代码是模拟,因此必须运行多次迭代,每次迭代都取决于邻居的结果。由于有很多数据,我决定使用流和平铺。

这是代码的简化方案:

sync = (int *)malloc(tiles * tiles * tiles * sizeof(*sync));
memset(sync, 0, tiles * tiles * tiles * sizeof(*sync));

// At the moment tiles = 4
for (i = 0; i < tiles * tiles * tiles; ++i) {
    cudaStreamCreate(&data[i].stream);
    data[i].sync = sync;
    data[i].tiles = tiles;
    data[i].x = i / (tiles * tiles);
    data[i].y = (i / tiles) % tiles;
    data[i].z = i % tiles;

    kernel<<<grid_size, block_size, 0, data[i].stream>>>(/* parameters */);

    cudaStreamAddCallback(data[i].stream, cudaCallback, &data[i], 0);
}

// Synchronization and respawn (now trying just 1 iteration, so no respawn)
for (i = 0; i < tiles * tiles * tiles; ++i) {
    printf("Waiting %d\n", i);
    while (sync[i] != iters) { __sync_synchronize(); }
}

回调:

void CUDART_CB cudaCallback(cudaStream_t stream, cudaError_t status, void *data)
{
    struct lifeStreamData *streamData = (struct lifeStreamData *)data;

    __sync_fetch_and_add(&streamData->sync[streamData->x * streamData->tiles * 
                    streamData->tiles + streamData->y * streamData->tiles +
                    streamData->z], 1);

    printf("Callback: done tile %d\n", streamData->x * streamData->tiles * streamData->tiles +
                streamData->y * streamData->tiles + streamData->z);
}

但这不起作用。仅调用最多55个回调。所以,程序挂在&#34;等待56&#34;。有4个瓦片,所以应该有64个回调。

也许内核运行得太快而无法设置回调?但为什么它适用于55而不是最后9?

内核是正确的(至少它没有挂起),因为它没有平铺正常运行,并且通过参数,可以更改大小和输入数据。

我知道代码不是最佳也不漂亮,但目前我正在努力使这项工作成功,所以我可以从这里进行优化。

1 个答案:

答案 0 :(得分:1)

在更改输入到内核的数据大小时,我错过了一个极端情况。这就是失败的原因。它现在正在运作。