-1
我正在編寫一些CUDA代碼。該代碼是一個模擬,所以它必須運行多次迭代,每次迭代都取決於鄰居的結果。由於有很多數據,我決定使用流和平鋪。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個回調。所以,該程序掛在「等待56」。有4個圖塊,所以應該有64個回調。
也許內核運行得太快以至於無法建立回調?但爲什麼它在55而不是在最後9?
內核是正確的(至少不會掛起),因爲它沒有平鋪正常運行,並且通過參數,可以更改大小和輸入數據。
我知道代碼不是最佳也不漂亮,但此刻我正在努力使這項工作,所以我可以從這裏優化。
您確定沒有任何API錯誤被報告? – talonmies
是的,對不起。在調整內核數據大小時,我錯過了一個角落案例。這是失敗:(我應該從首先看基本的東西開始。謝謝。 – markmb
如果這是解決方案,請添加它作爲這個問題的答案,以關閉它的未答覆列表 – talonmies