2011-03-15 59 views
0

嘿, 我有兩個2000的數組。我想編寫一個內核將一個數組複製到另一個數組。該陣列代表1000個粒子。索引0-999將包含一個x值和1000-1999位置的y值。CUDA - 指定<<<x,y> >> for for循環

我需要一個for循環來複制從1個數組到另一個數組的N粒子。例如:

int halfway = 1000; 
    for(int i = 0; i < N; i++){ 
     array1[i] = array2[i]; 
     array1[halfway + i] = array[halfway + i]; 
    } 

由於N的數量始終小於2000,我可以創建2000個線程嗎?或者我必須創建幾個塊。

我在想這樣一個內核中:

int tid = threadIdx.x; 

    if (tid >= N) return; 

    array1[tid] = array2[tid]; 
    array1[halfway + tid] = array2[halfway + tid]; 

,並調用它,如下所示:

kernel<<<1,2000>>>(...); 

將這項工作?它會很快嗎?或者我會更好地將問題分解成塊。我不知道如何做到這一點,也許(這是正確的?)

int tid = blockDim.x*blockIdx.x + threadIdx.x; 

    if (tid >= N) return; 

    array1[tid] = array2[tid]; 
    array1[halfway + tid] = array2[halfway + tid]; 

    kernel<<<4,256>>>(...); 

回答

3

將這項工作?

你真的試過了嗎?

它將無法啓動,因爲您最多可以有512個線程(值可能因體系結構不同而不同,我的是GTX 200系列之一)。您將需要更多的塊或更少的線程和內部的for循環,增量爲blockDim.x

您的多塊解決方案應該也能正常工作。

其他方法

如果這是內核的唯一目的,你不妨試試使用cudaMemcpycudaMemcpyDeviceToDevice作爲最後一個參數。

+0

我正在嘗試的東西出來,它只是需要接近10分鐘我的程序運行。當然,我認爲'cudaMemcpy'就夠了。你是說我的多塊解決方案可以像現在這樣工作,或者我需要一個帶有'blockDim.x'增量的for循環? 4是塊數的明智選擇?乾杯 – user660414 2011-03-15 16:29:09

+1

我還補充說,由於在主機和設備之間移動數據的速度有多慢,因此需要大量的計算才能使GPU的性價比更高。在這種情況下,如果內核比CPU上的簡單for循環更快,我會感到驚訝。 如果你正在用這些設備內存粒子陣列進行其他計算,我希望是這種情況,那麼值得的是什麼:) – tugudum 2011-03-15 16:31:10

+0

@ user660414您需要循環以支持大於4 * 256的數組。 – tugudum 2011-03-15 16:35:23

0

回答有關配置問題的唯一方法是測試它們。要做到這一點,編寫你的內核,以便它們工作,不管配置如何。通常,我會假設我將啓動足夠的線程,這使得內核更容易編寫。然後,我會做這樣的事情:

threads_per_block = 512; 

num_blocks = SIZE_ARRAY/threads_per_block; 
if(num_blocks*threads_per_block<SIZE_ARRAY) 
    num_blocks++; 

my_kernel <<< num_blocks, threads_per_block >>> (...); 

(除,當然,threads_per_block可能是一個定義,或命令行參數,或迭代測試許多配置)

0

是更好地使用更多對於任何內核來說都不止一塊。

它似乎對我來說,你是簡單地從一個數組複製到另一個作爲一個值的序列與偏移量。 如果是這樣,你可以簡單地使用cudaMemcpy API調用,並指定 cudaMemcpyDeviceToDevice

cudaMemcpy(array1+halfway,array1,1000,cudaMemcpyDeviceToDevice); 

的API會找出塊/線程的最佳分區的情況。

+0

由於設備的調度機制。每個GPU有多個SM,每個塊只能在一個SM上運行。如果您有多個模塊,則每個模塊都可以運行在不同的SM上,充分利用其硬件 – fabrizioM 2011-03-16 20:57:06

相關問題