2011-04-19 161 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