CUDA C:线程、线程块与线程格

相关阅读

CUDA Cicon-default.png?t=N7T8https://blog.csdn.net/weixin_45791458/category_12530616.html?spm=1001.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进行核函数调用checkIndex<<<grid, block>>>();//复位设备端cudaDeviceReset();return(0);
}

        因为printf函数只支持Fermi架构以上的GPU架构,所以在编译时需要指定架构为sm_20或以上,如下所示(默认情况下,nvcc会产生它所支持的最低版本架构的代码)。

$nvcc -arch=sm_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个月,但是发博客似乎已经成为了我的习惯,希望自己能一直坚持下去,努力提升自己的技术!

最后的最后:感谢我的父母和小李同学一直以来的支持与帮助!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/230897.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

docker在线安装minio

1、下载最新minio docker pull minio/minio 2、在宿主机创建 /usr/local/data/miniodocker/config 和 /usr/local/data/miniodocker/data,执行docker命令 docker run -p 9000:9000 -p 9090:9090 --name minio -d --restartalways -e MINIO_ACCESS_KEYminio -e MINIO_SECRET_K…

力扣225. 用队列实现栈【附进阶版】

文章目录 力扣225. 用队列实现栈示例思路及其实现两个队列模拟栈一个队列模拟栈 力扣225. 用队列实现栈 示例 思路及其实现 两个队列模拟栈 队列是先进先出的规则&#xff0c;把一个队列中的数据导入另一个队列中&#xff0c;数据的顺序并没有变&#xff0c;并没有变成先进后…

引领半导体划片机行业,实现钛酸锶基片切割的卓越效能

在当今快速发展的半导体行业中&#xff0c;博捷芯以其卓越的技术实力和精准的行业应用&#xff0c;脱颖而出&#xff0c;再次引领行业潮流。这次&#xff0c;他们将先进的BJX3356划片机技术应用于钛酸锶基片的切割&#xff0c;为半导体制造行业的进一步发展提供了强大的技术支持…

基于知识库的接口自动化测试——结果模型化方法与装置的分析

一、背景 随着自动化测试的设计理念不断完善、新的技术不断应用&#xff0c;自动化测试资产的积累代价和维护成本不断降低&#xff0c;自动化测试资产的数量持续增长。同时&#xff0c;随着DevOps的普及&#xff0c;应用研发过程越来越敏捷&#xff0c;自动化测试能力逐步从测…

js输入框部分内容不可编辑,其余正常输入,el-input和el-select输入框和多个下拉框联动后的内容不可修改

<tr>//格式// required自定义指令<e-td :required"!read" label><span>地区&#xff1a;</span></e-td><td>//v-if"!read && this.data.nationCode 148"显示逻辑<divclass"table-cell-flex"sty…

camera曝光时间

曝光和传感器读数 相机上的图像采集过程由两个不同的部分组成。第一部分是曝光。曝光完成后&#xff0c;第二步就是从传感器的寄存器中读取数据并传输&#xff08;readout&#xff09;。 曝光&#xff1a;曝光是图像传感器进行感光的一个过程&#xff0c;相机曝光时间&#xf…

技术阅读周刊第十期

技术阅读周刊&#xff0c;每周更新。 周四加了个班&#xff0c;周五没缓过来&#xff0c;就推迟到今天更新了 历史更新 20231117&#xff1a;第六期20231124&#xff1a;第七期20231201&#xff1a;第八期20231215&#xff1a;第九期 Golang: 14 Shorthand Tricks You Might No…

LLMs 玩狼人杀:清华大学验证大模型参与复杂交流博弈游戏的能力

作者&#xff1a;彬彬 编辑&#xff1a;李宝珠&#xff0c;三羊 清华大学研究团队提出了一种用于交流游戏的框架&#xff0c;展示了大语言模型从经验中学习的能力&#xff0c;还发现大语言模型具有非预编程的策略行为&#xff0c;如信任、对抗、伪装和领导力。 近年来&#x…

设计模式——迭代器模式

引言 迭代器模式是一种行为设计模式&#xff0c; 让你能在不暴露集合底层表现形式 &#xff08;列表、 栈和树等&#xff09; 的情况下遍历集合中所有的元素。 问题 集合是编程中最常使用的数据类型之一。 尽管如此&#xff0c; 集合只是一组对象的容器而已。 大部分集合使用…

Spring 原理(一)

Spring 原理 它是一个全面的、企业应用开发一站式的解决方案&#xff0c;贯穿表现层、业务层、持久层。但是 Spring仍然可以和其他的框架无缝整合。 Spring 特点 轻量级控制反转面向切面容器框架集合 Spring 核心组件 Spring 常用模块 Spring 主要包 Spring 常用注解 bean …

达索系统SOLIDWORKS 2024 云服务新功能

“云服务 是基于互联网的相关服务的增加、使用和交互模式&#xff0c;通常涉及通过互联网来提供动态易扩展且经常是虚拟化的资源。 云是网络、互联网的一种比喻说法。过去在图中往往用云来表示电信网&#xff0c;后来也用来表示互联网和底层基础设施的抽象。云服务指通过网络以…

小贴士:知道方程的解如何求通解

1.思路&#xff1a;认知&#xff1a;题中的所有解都是特解&#xff0c;解的形式为kxb 1.如何求通解&#xff1a;a1a2是题目中提供的条件&#xff0c;根据认知它们的和是2b&#xff0c;所以b等于a1a3除2&#xff0c;而有一条认知&#xff0c;为两个特解的差为通解向量&#xff0…

python绘图总结

1 二维图像 1.1 二维曲线 plot(x, y, ls"-", lw1.5, labelNone)x, y&#xff1a;横坐标和纵坐标ls&#xff1a;颜色、点标记、线型列表&#xff0c;如 ls‘r*-’ 表示红色实线、*形点&#xff0c;ls‘g.’ 表示绿色散点lw&#xff1a;线宽度label&#xff1a;线标签…

波奇学Linux:进程等待

僵尸进程(Z状态)无法被kill指令杀死&#xff0c;通过进程等待杀掉它&#xff0c;解决内存泄漏问题&#xff08;进程处于僵尸态&#xff0c;仍然维护pcb结构体来解决问题&#xff09; 通过进程等待&#xff0c;获得进程退出情况 wait回收僵尸态进程 我们可以看到进程由五秒后子…

php hyperf 读取redis,存储到数据库

redis中排行榜中的数据 public function execute(string $date){$query ChannelConfig::query();$query->where(module_name, rank_reward);$rewardData $query->first();$rewards [];if( $rewardData ){$rewardContents $rewardData->content;foreach ($rewardC…

VMware----基于 VMware 玩转 CentOS 虚拟机创建、克隆以及配置后台运行

查看原文 文章目录 一、安装 Vmware二、创建 CentOS7 系统的虚拟机三、克隆虚拟机四、设置虚拟机后台运行 一、安装 Vmware &#xff08;1&#xff09;打开VMware下载地址页面&#xff0c;滑动页面&#xff0c;找到如下界面&#xff0c;点击【下载】 &#xff08;2&#xff…

本地电商平台商业模式 同城实体店引流获客方法

本地电商平台的商业模式通常是基于在线市场交易的。这样的平台允许本地商家在其上发布商品信息&#xff0c;消费者可以在平台上选择购买&#xff0c;并直接向卖家付款。商家可以通过平台获得更广泛的市场覆盖和销售机会&#xff0c;同时消费者也可以享受更加便利和多样化的购物…

RPC(3):HttpClient实现RPC之GET请求

1HttpClient简介 在JDK中java.net包下提供了用户HTTP访问的基本功能&#xff0c;但是它缺少灵活性或许多应用所需要的功能。 HttpClient起初是Apache Jakarta Common 的子项目。用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包&#xff0c;并且它支持 H…

Neural Network——神经网络

1.feature reusing——特征复用 1.1 什么是特征复用 回顾我们之前所学习的模型&#xff0c;本质上都是基于线性回归&#xff0c;但却都可以运用于非线性相关的数据&#xff0c;包括使用了如下方法 增加更多的特征产生新的特征&#xff08;多项式回归&#xff09;核函数 在本身…

Spring IOC 原理(二)

Spring IOC 原理 概念 Spring 通过一个配置文件描述 Bean 及 Bean 之间的依赖关系&#xff0c;利用 Java 语言的反射功能实例化Bean 并建立 Bean 之间的依赖关系。 Spring 的 IoC 容器在完成这些底层工作的基础上&#xff0c;还提供了 Bean 实例缓存、生命周期管理、 Bean 实…