CUDA执行的确切行为是什么?

时间:2016-05-17 15:22:15

标签: cuda nvidia visual-studio-debugging

假设我们想要使用下面的代码调用全局函数。每个线程都有一个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个线程在同一时间,现在我怀疑

1 个答案:

答案 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