2011-04-27 72 views
1

我想編寫一個CUDA函數來提取滿足特定條件的圖像點,然後將它們放置在設備的連續內存塊中。CUDA:如何將特定圖像點提取爲連續矢量?

點在設備上的連續內存塊中的原因是,我可以立即使用塊和線程ID作爲此列表中點的索引並行處理這些點。

如果我使用相同的內核(函數)來檢測它們,我浪費了大部分線程,因爲我想爲每個圖像點分配一個線程,並且很少線程將屬於所需的點。其餘的線程將不得不坐下來等待。更不用說,正在處理所需點的線程將屬於不同的塊,嚴重破壞了首先並行操作的預期收益。

如果您對如何獲取一組積分以及將它們並行傳輸到設備上的新位置(!)有任何建議,我願意接受。謝謝你的時間。

回答

2

這裏是做到這一點的常見方法:

  • 內核1:提取圖像點,並將其寫入到陣列。數組中的結果是非連續的。
  • 將非連續數組中的點收集到連續數組中。
  • 內核2:處理圖像點。

內核1可能會將圖像點寫入有空隙的數組中,因爲您無法預測將會產生多少圖像點。所以,你需要聚集書面圖像點在一起,然後運行它的內核2。如果你使用類似Thrust這樣的庫,這個聚會很容易。例如,其remove_if函數可用於刪除標記爲無效或空白的點。

+0

謝謝,我會試試看! – 2011-04-27 06:19:54

0

,你也可以嘗試直接添加成果轉化,用原子功能:

__global__ void kernel(dataType *inputImage, dataType *a, int *sizeof_A) 
{ 
    // map from threadIdx/BlockIdx to pixel position 
    int x = threadIdx.x + blockIdx.x * blockDim.x; 
    int y = threadIdx.y + blockIdx.y * blockDim.y; 
    int offset = x + y * blockDim.x * gridDim.x; 

    if (inputImage[offset] == /* your condition */) { 
     int arrayLastPosition = atomicAdd(sizeof_A, 1); 
     a[arrayLastPosition] = /* your mark */; 
    } 
} 

您將在sizeof_A數組的長度在這個內核年底輸出向量,即。這是一種幼稚的方法,但將它與收集元素以在數組開始時移動它們的中間步驟相比可能會很有趣。

+0

對於非稀疏輸出情況以外的任何情況,原子內存訪問將比在輸出上運行單獨的流壓縮內核慢得多。 – talonmies 2011-04-27 15:01:02

+0

在共享內存中還原子化? – pQB 2011-04-28 07:23:30