CUDA编程模型#2

线程管理

由一个内核启动所产生的所有线程统称为一个网格。同一网格中的所有线程共享相同的全局内存空间。一个网格由多个线程块构成,一个线程块包含一组线程,同一线程块内的线程协作可以通过以下方式来实现。

  • 同步
  • 共享内存

不同块内的线程不能协作。

线程依靠以下两个坐标变量来区分彼此。

  • blockIdx(线程块在线程格内的索引)
  • threadIdx(块内的线程索引)

执行一个核函数时,CUDA运行时为每个线程分配坐标变量blockIdx和threadIdx。基于这些坐标,可以将部分数据分配给不同的线程。

该坐标变量是基于uint3定义的cuda内置的向量类型,是一个包含3个无符号整数的结构,可以通过x,y,z三个字段来指定。

blockIdx.x
blockIdx.y
blockIdx.z
threadIdx.x
threadIdx.y
threadIdx.z

CUDA可以组织三维的网格和块。网格和块的维度由下列两个内置变量指定

  • blockDim(线程块的维度,用每个线程块中的线程数来表示)
  • gridDim(线程格的维度,用每个线程格中的线程数来表示)

它们是dim3类型的变量,基于uint3定义的整数型向量,用来表示维度。

在CUDA程序中,有两组不同的网格和块变量:手动定义的dim3数据类型和预定义的uint3数据类型。在主机端,作为内核调用的一部分,可以使用dim3数据类型定义一个网格和块的维度。当执行核函数时,CUDA运行时会生成相应的内置预初始化的网格、块和线程变量,它们在核函数内均可被访问到且为uint3类型。

举个栗子

#include <cuda_runtime.h>
#include <stdio.h>
#include <cstdlib>

__global__ void checkIndex(){
        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 main(int argc, char **argv){
        int nElem = std::atoi(argv[1]);

        dim3 block (3);
        dim3 grid ((nElem+block.x-1)/block.x);

        fprintf(stdout,"grid.x %d, grid.y %d, grid.z %d\n",grid.x, grid.y, grid.z);
        fprintf(stdout,"block.x %d, block.y %d, block.z %d\n",block.x, block.y, block.z);

        checkIndex<<<grid, block>>>();

        cudaDeviceReset();

        return 0;
}

运行命令

nvcc -o check checkDimension.cu

./check 3

运行结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值