网站收录低的原因,asp 网站开发教程,百度网页打不开,商城网站建设一般需要多少钱相关阅读
CUDA Chttps://blog.csdn.net/weixin_45791458/category_12530616.html?spm1001.2014.3001.5482 第一百篇博客#xff0c;写点不一样的。 当核函数在主机端被调用时#xff0c;它会被转移到设备端执行#xff0c;此时设备会根据核函数的调用格式产生对应的线程(…相关阅读
CUDA Chttps://blog.csdn.net/weixin_45791458/category_12530616.html?spm1001.2014.3001.5482 第一百篇博客写点不一样的。 当核函数在主机端被调用时它会被转移到设备端执行此时设备会根据核函数的调用格式产生对应的线程(thread)并且每个线程都执行核函数指定的语句。 CUDA提供了线程的层次结构以便于组织线程自顶而下可以分为线程格、线程块和线程。由一个内核启动的所有线程统称为一个线程格(grid)同一线程格中的所有线程共享相同的全局内存空间。一个线程格由多个线程块(block)构成一个线程块由包含若干线程同一线程块内的线程可以通过以下两种方式协作而不同线程块内线程不能协作。
同步共享内存 线程通过下面两个核函数的预置变量来区分彼此预置变量代表着CUDA在运行时为每一个进程都分配了这两个变量基于这两个变量可以将一块数据分给不同的进程处理。
blockIdx线程块在线程格内的索引threadIdx线程在线程块中的索引 这两个变量是由一个名为uint3的结构定义的这实际上就是CUDA内置的一个包含三个无符号整数的结构体如下所示。
//这个定义在vector_types.h头文件中
struct __device_builtin__ uint3
{unsigned int x, y, z;
};typedef __device_builtin__ struct uint3 uint3; 根据定义这两个变量可以通过下面的方式访问结构的成员。
blockIdx.x //线程块索引的x分量
blockIdx.y //线程块索引的y分量
blockIdx.z //线程块索引的y分量
threadIdx.x //线程索引的x分量
threadIdx.y //线程索引的y分量
threadIdx.z //线程索引的z分量 为什么这两个结构都是三个分量因为CUDA最多支持组织三维的层次结构即线程块在线程格中的分布最多有三个维度而线程在线程块中的分布最多有三个维度。CUDA使用了下面两个预置变量来保存层次结构的维度大小。
blockDim线程块的维度大小用线程块中的线程数来表示gridDim线程格的维度大小用线程格中的线程块数来表示 这两个预置变量是由一个名为dim3的结构定义的这实际上也是CUDA内置的一个包含三个无符号整数的结构体如下所示。
//这个定义在vector_types.h头文件中
struct __device_builtin__ dim3
{unsigned int x, y, z;
#if defined(__cplusplus)
#if __cplusplus 201103L__host__ __device__ constexpr dim3(unsigned int vx 1, unsigned int vy 1, unsigned int vz 1) : x(vx), y(vy), z(vz) {}__host__ __device__ constexpr dim3(uint3 v) : x(v.x), y(v.y), z(v.z) {}__host__ __device__ constexpr operator uint3(void) const { return uint3{x, y, z}; }
#else__host__ __device__ dim3(unsigned int vx 1, unsigned int vy 1, unsigned int vz 1) : x(vx), y(vy), z(vz) {}__host__ __device__ dim3(uint3 v) : x(v.x), y(v.y), z(v.z) {}__host__ __device__ operator uint3(void) const { uint3 t; t.x x; t.y y; t.z z; return t; }
#endif
#endif /* __cplusplus */
};typedef __device_builtin__ struct dim3 dim3; 根据定义这两个变量可以通过下面的方式访问结构的成员。
blockDim.x //线程块x方向的维度大小
blockDim.y //线程块y方向的维度大小
blockDim.z //线程块z方向的维度大小
gridDim.x //线程格x方向的维度大小
gridDim.y //线程格y方向的维度大小
gridDim.z //线程格z方向的维度大小 通常情况下一个线程格拥有两个维度即一个线程块拥有三个维度。如果维度数小于3则多余的维度对应的Dim变量成员会被初始化为1。 需要特别说明的是上面谈到的四个预置变量只有在核函数内部也可以说设备端才能访问到。而在主机端为了调用核函数可以自行定义dim3数据类型的变量这些在主机端定义的变量在核函数内部是不可访问的。 下面的程序验证了如何使用这些预置变量以及自行定义dim3数据类型的变量。
#include cuda_runtime.h
#include stdio.h__global__ void checkIndex(void) //定义核函数显示本进程的预置变量
{printf(threadIdx:(%d, %d, %d)\n, threadIdx.x, threadIdx.y, threadIdx.z);printf(blockIdx:(%d, %d, %d)\n, blockIdx.x, blockIdx.y, blockIdx.z);printf(blockDim:(%d, %d, %d)\n, blockDim.x, blockDim.y, blockDim.z);printf(gridDim:(%d, %d, %d)\n, gridDim.x, gridDim.y, gridDim.z);}int main(int argc, char **argv)
{//定义数据量int nElem 6;//定义了两个dim类型的变量block和grid用于核函数调用dim3 block(3); //注意这里使用了构造函数创建结构变量dim3 grid((nElem block.x - 1) / block.x);//显示block和grid的分量值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);//使用block和grid进行核函数调用checkIndexgrid, block();//复位设备端cudaDeviceReset();return(0);
} 因为printf函数只支持Fermi架构以上的GPU架构所以在编译时需要指定架构为sm_20或以上如下所示默认情况下nvcc会产生它所支持的最低版本架构的代码。
$nvcc -archsm_20 checkDimension.cu -o check
$./check 程序的输出如下所示。
grid.x 2 grid.y 1 grid.z 1
block.x 3 block.y 1 block.z 1
threadIdx:(0, 0, 0)
threadIdx:(1, 0, 0)
threadIdx:(2, 0, 0)
threadIdx:(0, 0, 0)
threadIdx:(1, 0, 0)
threadIdx:(2, 0, 0)
blockIdx:(0, 0, 0)
blockIdx:(0, 0, 0)
blockIdx:(0, 0, 0)
blockIdx:(1, 0, 0)
blockIdx:(1, 0, 0)
blockIdx:(1, 0, 0)
blockDim:(3, 1, 1)
blockDim:(3, 1, 1)
blockDim:(3, 1, 1)
blockDim:(3, 1, 1)
blockDim:(3, 1, 1)
blockDim:(3, 1, 1)
gridDim:(2, 1, 1)
gridDim:(2, 1, 1)
gridDim:(2, 1, 1)
gridDim:(2, 1, 1)
gridDim:(2, 1, 1)
gridDim:(2, 1, 1) 写在最后这是我的第100篇博客回想从写第一篇博客到现在也只有短短10个月但是发博客似乎已经成为了我的习惯希望自己能一直坚持下去努力提升自己的技术
最后的最后感谢我的父母和小李同学一直以来的支持与帮助