2015-11-03 93 views
0

CUDA documentation建議使用cudaMemCpy2D()用於2D陣列(以及類似地cudaMemCpy3D()用於3D陣列),而不是用於cudaMemCpy()更好的性能更適當地前者分配器件存儲器中連續行。另一方面,所有cudaMemCpy函數,就像memcpy()一樣,都需要連續分配內存。2D陣列,在堆存儲器cudaMemCpy2D()

如果我將我的(主機)陣列創建爲例如float myArray[h][w];,那麼這很好。

float** myArray2 = new float*[h]; 
for(int i = 0 ; i < h ; i++){ 
    myArray2[i] = new float[w]; 
} 

這不是當一個人試圖實現CUDA到現有的項目,這是我面臨的問題,除了一個大問題:但是,它很可能不會,如果我使用類似的工作。現在,我創建一個臨時一維數組,將我的二維數組的內容複製到其中,並使用cudaMemCpy()並重復整個過程以在內核啓動後獲得結果,但這似乎不是一種優雅/有效的方式。

有沒有更好的方法來處理這種情況?具體來說,有沒有辦法在堆上連續分配行來創建真正的二維數組,以便我可以使用cudaMemCpy2D()

PS:我找不到這個問題的答案如下以前類似的帖子:(在 第二個答案這個是相當令人費解)

+0

我不清楚爲什麼你的第二個環節不是解決方案。 –

+0

@AnonMail,我可能是錯的,但在這個問題中定義了一個容器(類似於std :: vector)。它在內部使用一維數組來實現連續分配。也類似於std :: vector和std :: map,不能使用指針直接訪問容器的元素,而應該使用迭代器。我懷疑可以使用memcpy()複製這些對象的內容。 –

+0

@RobertCrovella,感謝您的評論。這(在HostToDevice副本之前手動壓扁2D陣列)正是我現在在我的應用程序中所做的。我希望能找到一種方法來改變它,所以我可以利用cudaMemCpy2D()的更高效的內存分配。看起來這是唯一的方法。 –

回答

2

分配大數組,然後使用指針算法來查找行的實際開始。

float* bigArray = new float[h * w] 
float** myArray2 = new float*[h] 
for(int i = 0 ; i < h ; i++){ 
    myArray2[i] = &bigArray[i * w]; 
} 

你的指針數組myArray2給你C/C++式二維陣列的行爲,bigArray給你的存儲器由CUDA所需的連續塊中。

+0

謝謝,@戴爾威爾遜。只是爲了澄清,這樣我可以將myArray2傳遞給cudaMemCpy2D(),對不對? –

+0

請注意,我編輯我的帖子,使第一行新float [h * w]而不是新float * [h * w]。對於錯字感到抱歉。現在談談你的問題:你應該使用bigArray將數組傳遞給CUDA,但是你也可以使用myArray [0]。在任何情況下,您都需要一個指向連續浮點數組的指針,而不是指向數組的指針,這是傳遞myArray2會給你的指針。 –

+0

太棒了!這正是我所希望的。謝謝。 –