假设我们想要使用下面的代码调用全局函数。每个线程都有一个curandState生成器和一个int数组(都正确初始化),我们将使用它们来执行以下代码示例:
#define NUMTHREADS 200
int main(){
int * result;
curandState * randState;
if (cudaMalloc(&randState, NUMTHREADS * sizeof(curandState)) == cudaErrorMemoryAllocation ||
cudaMalloc(&result, NUMTHREADS * sizeof(int)) == cudaErrorMemoryAllocation){
cudaDeviceReset();
exit(-1);
}
setup_cuRand <<<1, NUMTHREADS>>> (randState, unsigned(time(NULL)));
method <<<1, NUMTHREADS>>> (state,result);
return 1;
}
__global__ void setup_cuRand(curandState * state, unsigned long seed)
{
int id = threadIdx.x;
curand_init(seed, id, 0, &state[id]);
}
__global__ void generic method(curandState* state, int * result){
curandState localState = state[threadIdx.x];
int num = curand(&localState) % 100;
if(num > 50)
result[threadIdx.x] = threadIdx.x;
else
result[threadIdx.x] = -1;
}
我们会执行什么?我的意思是,线程是否神奇地分成两个代码并稍后重新加入或者它是如何工作的?是否一次执行1024个线程?最后一个问题是因为当我在Visual Studio 2013上调试时,使用Cuda Debugger,当我继续前进时,threadIdx.x总是有一个像n*32
的值,直到现在我认为可以执行1024个线程在同一时间,现在我怀疑
答案 0 :(得分:3)
测试可能会转换为谓词,这意味着在您的内存区域中有条件地赋值。如果你的if更复杂,那么warp的线程会在if
子句的第二部分之后神奇地 join 。根据warp的每个线程的谓词,甚至可能不会访问分支。
输入断点时,将显示特定线程/块ID的数据。 NSOME for Visual Studio中的 CUDA Debug Focus 设置给出了哪个线程/块(使用CUDA进行调试时,输入NSIGHT菜单项,然后选择Windows,然后选择CUDA Debug Focus ...)默认情况下,线程0,0,0将被聚焦。
线程在逻辑上同时执行,但实际上,每个SM的CUDA核心数少于1024个。线程被组织成32的warp,并且指令调度器在不同的执行单元上调度warp。 对于1024个线程,即32个warp,第一个和最后一个warp不一定精确地同时执行。
有关详细信息,请参阅cuda文档中的Memory Fence函数,以及Synchronization Functions。