2011-04-19 123 views
20

我有一個內核調用if語句中的設備函數函數。代碼如下:CUDA:從內核調用__device__函數

__device__ void SetValues(int *ptr,int id) 
{ 
    if(ptr[threadIdx.x]==id) //question related to here 
      ptr[threadIdx.x]++; 
} 

__global__ void Kernel(int *ptr) 
{ 
    if(threadIdx.x<2) 
     SetValues(ptr,threadIdx.x); 
} 

在內核線程0-1中同時調用SetValues。那之後會發生什麼?我的意思是現在有2個併發呼叫SetValues。每個函數調用是否都是串行執行的?所以他們的行爲就像2個內核函數調用一樣?

回答

22

CUDA默認內聯了所有函數(雖然Fermi和更新的架構也支持帶有函數指針和實函數調用的正確ABI)。所以,你的示例代碼被編譯到這樣的事情

__global__ void Kernel(int *ptr) 
{ 
    if(threadIdx.x<2) 
     if(ptr[threadIdx.x]==threadIdx.x) 
      ptr[threadIdx.x]++; 
} 

執行並行發生,就像正常的代碼。如果你將一個內存競爭設計成一個函數,那麼沒有序列化機制可以爲你節省。

+0

我有一張費米卡。這是否意味着函數是非內聯的?因此SetValues中的threadIdx.x是所有線程,而不僅僅是線程0和1? – scatman 2011-04-19 06:58:53

+1

Fermi默認仍然內聯函數。我想我明白你現在問的是什麼 - 這是每個線程變量(如threadIdx)內置的__device__函數內部的範圍。我變暖了嗎? – talonmies 2011-04-19 07:16:48

+0

是的,這是我的問題。但由於__device__函數是內聯的..那麼我猜測線程的範圍與使用<<<塊,線程>>>調用的範圍相同,但由於分支只有線程0和1執行ptr [threadIdx.x] ++。它是否正確? – scatman 2011-04-19 07:31:17