2015-11-19 49 views
-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?

內核是正確的(至少不會掛起),因爲它沒有平鋪正常運行,並且通過參數,可以更改大小和輸入數據。

我知道代碼不是最佳也不漂亮,但此刻我正在努力使這項工作,所以我可以從這裏優化。

+3

您確定沒有任何API錯誤被報告? – talonmies

+0

是的,對不起。在調整內核數據大小時,我錯過了一個角落案例。這是失敗:(我應該從首先看基本的東西開始。謝謝。 – markmb

+0

如果這是解決方案,請添加它作爲這個問題的答案,以關閉它的未答覆列表 – talonmies

回答

1

在更改輸入到內核的數據大小時,我錯過了一個角落案例。這就是它失敗的原因。它正在工作。

相關問題