线程是程序执行流的最小单元。一个标准的线程由线程ID,当前指令指针(PC),寄存器集合和堆栈组成。而线程是进程中的一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。
一个线程束由32个连续的线程组成,在一个线程束中,所有的线程按照单指令多线程(SIMT)方式执行;即,所有线程都执行相同的指令,每个线程在私有数据上进行操作。
由于线程束分化,应该避免在同一线程束中有不同的执行路径,即确保同一个线程束中的所有线程在一个应用程序中使用同一个控制路径
CUDA内核启动时,线程块分布在多个SM中。网格中的线程块以并行或连续或任意的顺序被执行。这种独立性使得CUDA程序在任意数量的计算核心间可以扩展。
#include
#include
#define CHECK(call) \
{ \
const cudaError_t error =call; \
if(error != cudaSuccess) \
{ \
printf("Error: %s:%d,", __FILE__, __LINE__); \
printf("code:%d, reason: %s \n",error,cudaGetErrorString(error)); \
exit(1); \
} \
}
__global__ void checkIndex(void)
{
printf("threadIdx:(%d, %d, %d) "
"blockIdx:(%d, %d, %d) "
"blockDim:(%d, %d, %d) "
"gridDim:(%d, %d, %d)\n",
threadIdx.x,threadIdx.y,threadIdx.z,
blockIdx.x,blockIdx.y,blockIdx.z,
blockDim.x,blockDim.y,blockDim.z,
gridDim.x,gridDim.y,gridDim.z);
int idx = blockIdx.x*blockDim.x+threadIdx.x;
printf("blockIdx =%d blockDim.x =%d threadIdx.x =%d idx =%d \n",
blockIdx.x,blockDim.x,threadIdx.x,idx);
}
int main(int argc, char **argv)
{
int nElem =6;
dim3 block(3);
dim3 grid((nElem+block.x-1)/block.x);
printf("grid.x=%d, grid.y=%d, grid.z=%d \n",grid.x,grid.y,grid.z);
printf("block.x=%d, block.y=%d, block.z=%d \n",block.x,block.y,block.z);
checkIndex<<>>();
//cudaDeviceReset();
CHECK(cudaDeviceSynchronize());
return 0;
}