2011-11-21 162 views
0

我需要使計算的一部分是並行的。它是關於矢量的計算,有時我需要對每個值進行一次操作。所以我想讓它平行。Cuda如何從全局函數運行多個線程?一個運行多線程的內核

我不能解釋我的計算示例(它只是一個簡單的例子,不是我的算法): 我正在向前移動一個指針,當我找到第5個數字時,我將向矢量中的每個數字加上5。

所以我想避免這樣做對主機和複製所有大載體,設備的每一個指針移動後< =>主機(repetable)。我想它可能比主機上的所有東西都低效。

所以我有一個想法,我將所有的向量複製到設備一次,然後我就開始算法。

下面是一個簡單的應對提出我的問題:

__device__ void devFunction(long long unsigned int *arr, long long unsigned int param, long long unsigned int N) { 
    long long unsigned int i = blockIdx.x* blockDim.x+ threadIdx.x; 
    // do something ... 
} 

__global__ void globFunction(long long unsigned int *arr, long long unsigned int N) { 

    do { 
     devFunction(arr, param, N); // I want to run many threads here like <<<...>>> 

     // do something ... 

    } while(/* ... */); 
} 


int main() { 
    // declare array, alloc memory, copy memory, etc. 
    globFunction<<< 400000, 256>>>(arr, N); // I think here should be <<<1,1>>> 
    // do something ... 
    return 0; 
} 

所以這是可以做到的呢?從內核並行運行多個函數?其他解決方案?

+0

爲什麼你需要從一個cuda線程產生更多的線程?難道你不能在主機的許多線程上調用內核並且同時運行計算嗎? – Tudor

+0

它可能會比較慢,因爲每個線程都會執行相同的思考 - >通過這個Big vector向前移動指針並將其與數字5進行比較(在示例中)。我只需要在一個線程中執行一次並且只執行一次。只有每個線程上的其他計算。 – nosbor

+0

@nosbor:所以你想知道是否有可能「平行做事」?這不是一個非常確切的問題,是嗎? – talonmies

回答

5

不,那是不可能的。但是,你可能要對這個錯誤的方式:只有主內核函數應該有必要計算線程索引,你應該以這樣的方式,每個線程擁有獨立工作做設計的代碼。這是可並行化問題的本質。並行代碼中不應該存在分支或跨線程數據依賴性。

的粗骨架例如,代碼應該是這個樣子:

__global__ void kernel(int * indata, int * outdata) 
{ 
    unsigned int tid = threadId.x + blockDim.x * blockId.x; // or suitable analogue 

    device_computation(indata + tid, outdata + tid); 
} 

__device__ void device computation(int * in, int * out) 
{ 
    // This code does not care about the thead ID 
    // -- it is already local to one single thread 
    *out = *in * 2; 
} 

你真的不應該有任何需要知道indata[j]爲了計算indata[i]。如果你這樣做,那麼你就必須重新分區的數據,使得該對執行計算所需的所有數據可見專門爲一個單獨的線程。

如果代碼不能這樣設計的,它會受到嚴重的性能命中,你應該調查是否實際上是值得並行化。

(該示例過於簡單;應該考慮使用塊共享內存的機會,但這並不影響每個線程都應該獨立於其他線程運行的事實。)

+0

是的,但是當您考慮示例問題時,無法使其看起來像這樣。 – nosbor

+0

@nosbor:我看不出你的代碼在做什麼,但你應該嘗試將它分成可以獨立完成的部分,或者用最少的同步。 –