2011-10-06 38 views
1

以下,我有做這些件代碼,用於在GPU處理的圖像的問題在過濾器工作的輸入:與該塊的輸出中的CUDA濾波器是下一個塊

for(int h=0; h<height; h++) { 
    for(int w=1; w<width; w++) { 
    image[h][w] = (1-a)*image[h][w] + a*image[h][w-1]; 
    } 
} 

如果我定義:

爲dim3 threads_perblock(32,32)

然後每個塊我有:32個線程可被傳遞。該塊的線程無法與來自其他塊的線程進行通信。

在一個thread_block中,我可以使用shared_memory翻譯這些代碼段,但是,對於邊緣(我會說):image [0,31]和image [0,32]在不同的線程塊中。圖像[0,31]應該從圖像[0,32]中獲取值來計算其值。但他們在不同的線程塊。

這樣的問題。

我該如何解決這個問題?

在此先感謝。

+0

您是否使用相同的緩衝區進行讀取和寫入?如果a = 1,那麼您正在將數據向右移動一列。那是你想要計算的嗎? – pQB

+0

這是CPU中的示例代碼,讀寫應該在GPU中不同。對於等待很簡單,因爲它不再是並行通信,任何其他想法?提前致謝。 – olidev

回答

1

如果image在全局內存中,那就沒有問題 - 你不需要使用共享內存,你可以直接從image直接訪問像素沒有任何問題。

但是,如果您在此之前已經完成了一些處理,並且一塊image已經在共享內存中,那麼您遇到了問題,因爲您需要執行超出塊範圍的鄰域操作。您可以執行下列操作之一 - 要麼:

  • 寫共享內存回全局內存,使其相鄰塊訪問(缺點:性能,模塊之間的同步可能會非常棘手)

或:

  • 爲每個塊重疊處理額外的邊緣像素(在這種情況下爲1像素),以便每個塊都有額外的像素來處理邊緣情況,例如具有34x34的塊大小工作,但僅存儲32×32中央輸出像素(的缺點:需要內核內附加邏輯,分支可以導致經發散,而不是在塊中的所有線程都充分使用)

不幸的是鄰域操作可以是在CUDA中真的很棘手,並且無論您用什麼方法處理邊緣案例,總是存在一個缺點。

+0

Hi @Paul。感謝您的回答。不過,我認爲你提出的兩種方法都不能解決問題。我正在尋找更多關於它 – olidev

+0

如果它是全局內存,位置32上的線程想要解決位置31中的線程,但它不可能。所以你不能用我認爲的全球記憶。沒有使用share_memory,沒有從圖像讀取值的順序 – olidev

+0

@devn:no,對於* global *內存任何線程都可以訪問任何全局內存位置 - 只有* shared *內存對於給定的線程塊是私有的 –

0

您可以使用繁忙的旋轉(無笑話)。只要使線程處理的[32]執行:

while(!variable); 

開始計算之前,線程處理[31]做

variable = 1; 

當它完成。這是由你來概括這一點。我知道這在CUDA中被認爲是「流氓編程」,但它似乎是實現您想要的唯一方法。我有一個非常類似的問題,它爲我工作。雖然你的表現可能會受到影 不過要小心,那

dim3 threads_perblock(32, 32) 

意味着你必須每塊32×32 = 1024個線程。