GPU CUDA之——深入理解threadIdx
http://blog.csdn.net/canhui_wang/article/details/51730264
摘要
本文主要讲述CUDA的threadIdx。
1. Grid,Block和Thread三者的关系
其中,一个grid包含多个blocks,这些blocks的组织方式可以是一维,二维或者三维。任何一个block包含有多个Threads,这些Threads的组织方式也可以是一维,二维或者三维。举例来讲:比如上图中,任何一个block中有10个Thread,那么,Block(0,0)的第一个Thread的ThreadIdx是0,Block(1,0)的第一个Thread的ThreadIdx是11;Block(2,0)的第一个Thread的ThreadIdx是21,......,依此类推,不难整理出其中的映射公式(表达式已在代码中给出)。
2. GridID,BlockID,ThreadID三者的关系
ThreadID是线性增长的,其目的是用于在硬件和软件上唯一标识每一个线程。CUDA程序中任何一个时刻,每一个线程的ThreadIdx都是特定唯一标识的!grid,block的划分方式不同,比如一维划分,二维划分,或者三维划分。显然,Threads的唯一标识ThreadIdx的表达方式随着grid,block的划分方式(或者说是维度)而不同。下面通过程序给出ThreadIdx的完整的表达式。其中,由于使用的时候会考虑到GPU内存优化等原因,代码可能也会有所不同,但是threadId的计算的表达式是相对固定的。
- /**************************************************************/
- // !!!!!!!!!!!!!!注意!!!!!!!!!!!!!!!!
- /**************************************************************/
- // grid划分成a维,block划分成b维,
- // 等价于
- // blocks是a维的,Threads是b维的。
- // 这里,本人用的是第一中说法。
- /**************************************************************/
- // 情况1:grid划分成1维,block划分为1维。
- __device__ int getGlobalIdx_1D_1D() {
- int threadId = blockIdx.x *blockDim.x + threadIdx.x;
- return threadId;
- }
- // 情况2:grid划分成1维,block划分为2维。
- __device__ int getGlobalIdx_1D_2D() {
- int threadId = blockIdx.x * blockDim.x * blockDim.y
- + threadIdx.y * blockDim.x + threadIdx.x;
- return threadId;
- }
- // 情况3:grid划分成1维,block划分为3维。
- __device__ int getGlobalIdx_1D_3D() {
- int threadId = blockIdx.x * blockDim.x * blockDim.y * blockDim.z
- + threadIdx.z * blockDim.y * blockDim.x
- + threadIdx.y * blockDim.x + threadIdx.x;
- return threadId;
- }
- // 情况4:grid划分成2维,block划分为1维。
- __device__ int getGlobalIdx_2D_1D() {
- int blockId = blockIdx.y * gridDim.x + blockIdx.x;
- int threadId = blockId * blockDim.x + threadIdx.x;
- return threadId;
- }
- // 情况5:grid划分成2维,block划分为2维。
- __device__ int getGlobalIdx_2D_2D() {
- int blockId = blockIdx.x + blockIdx.y * gridDim.x;
- int threadId = blockId * (blockDim.x * blockDim.y)
- + (threadIdx.y * blockDim.x) + threadIdx.x;
- return threadId;
- }
- // 情况6:grid划分成2维,block划分为3维。
- __device__ int getGlobalIdx_2D_3D() {
- int blockId = blockIdx.x + blockIdx.y * gridDim.x;
- int threadId = blockId * (blockDim.x * blockDim.y * blockDim.z)
- + (threadIdx.z * (blockDim.x * blockDim.y))
- + (threadIdx.y * blockDim.x) + threadIdx.x;
- return threadId;
- }
- // 情况7:grid划分成3维,block划分为1维。
- __device__ int getGlobalIdx_3D_1D() {
- int blockId = blockIdx.x + blockIdx.y * gridDim.x
- + gridDim.x * gridDim.y * blockIdx.z;
- int threadId = blockId * blockDim.x + threadIdx.x;
- return threadId;
- }
- // 情况8:grid划分成3维,block划分为2维。
- __device__ int getGlobalIdx_3D_2D() {
- int blockId = blockIdx.x + blockIdx.y * gridDim.x
- + gridDim.x * gridDim.y * blockIdx.z;
- int threadId = blockId * (blockDim.x * blockDim.y)
- + (threadIdx.y * blockDim.x) + threadIdx.x;
- return threadId;
- }
- // 情况9:grid划分成3维,block划分为3维。
- __device__ int getGlobalIdx_3D_3D() {
- int blockId = blockIdx.x + blockIdx.y * gridDim.x
- + gridDim.x * gridDim.y * blockIdx.z;
- int threadId = blockId * (blockDim.x * blockDim.y * blockDim.z)
- + (threadIdx.z * (blockDim.x * blockDim.y))
- + (threadIdx.y * blockDim.x) + threadIdx.x;
- return threadId;
- }
3. GPU Threads与CPU Threads的比较
GPU Threads的生成代价小,是轻量级的线程;CPU Threads的生成代价大,是重量级的线程。CPU Threads虽然生成的代价高于GPU Threads,但其执行效率高于GPU Threads,所以GPU Threads无法在个体的比较上取胜,只有在数量上取胜。在这个意义上来讲,CPU Threads好比是一头强壮的公牛在耕地,GPU Threads好比是1000头弱小的小牛在耕地。因此,为了保证体现GPU并行计算的优点,线程的数目必须足够多,通常至少得用上1000个GPU线程或者更多才够本,才能很好地体现GPU并行计算的优点!
4. GPU Threads的线程同步
线程同步是针对同一个block中的所有线程而言的,因为只有同一个block中的线程才能在有效的机制中共同访问shared memory。要知道,由于每一个Thread的生命周期长度是不相同的,Thread对Shared Memory的操作可能会导致读写的不一致,因此需要线程的同步,从而保证该block中所有线程同时结束。
GPU CUDA之——深入理解threadIdx的更多相关文章
- GPU,CUDA,cuDNN的理解
最近用到这方面的知识,感觉这篇文章写的很好,为了方便自己查阅,就搬运了过来,如果牵涉到侵权,请联系我,我会删除该博文!!! 我们知道做深度学习离不开GPU,不过一直以来对GPU和CPU的差别,CUDA ...
- 真实机下 ubuntu 18.04 安装GPU +CUDA+cuDNN 以及其版本选择(亲测非常实用)【转】
本文转载自:https://blog.csdn.net/u010801439/article/details/80483036 ubuntu 18.04 安装GPU +CUDA+cuDNN : 目前, ...
- GPU CUDA编程中threadIdx, blockIdx, blockDim, gridDim之间的区别与联系
前期写代码的时候都会困惑这个实际的threadIdx(tid,实际的线程id)到底是多少,自己写出来的对不对,今天经过自己一些小例子的推敲,以及找到官网的相关介绍,总算自己弄清楚了. 在启动kerne ...
- [GPU] CUDA for Deep Learning, why?
又是一枚祖国的骚年,阅览做做笔记:http://www.cnblogs.com/neopenx/p/4643705.html 这里只是一些基础知识.帮助理解DL tool的实现. 最新补充:我需要一台 ...
- OpenCV GPU CUDA OpenCL 配置
首先,正确安装OpenCV,并且通过测试. 我理解GPU的环境配置由3个主要步骤构成. 1. 生成关联文件,即makefile或工程文件 2. 编译生成与使用硬件相关的库文件,包括动态.静态库文件. ...
- GPU CUDA 经典入门指南
转自:http://luofl1992.is-programmer.com/posts/38830.html CUDA编程中,习惯称CPU为Host,GPU为Device.编程中最开始接触的东西恐怕是 ...
- GPU/CUDA程序初体验 向量加法
现在主要的并行计算设备有两种发展趋势: (1)多核CPU. 双核,四核,八核,...,72核,...,可以使用OpenMP编译处理方案,就是指导编译器编译为多核并行执行. (2)多线程设备(GP)GP ...
- ubuntu16.04+caffe+GPU+cuda+cudnn安装教程
步骤简述: 1.安装GPU驱动(系统适配,不采取手动安装的方式) 2.安装依赖(cuda依赖库,caffe依赖) 3.安装cuda 4.安装cudnn(只是复制文件加链接,不需要编译安装的过程) 5. ...
- GPU && CUDA:主机和设备间数据传输测试
数据传输测试,先从主机传输到设备,再在设备内传输,再从设备传输到主机. H-->D D-->D D-->H // moveArrays.cu // // demonstrates C ...
随机推荐
- 错误:严重: Servlet.service() for servlet [appServlet] in context with path [] threw exception [Request processing failed; nested exception is org.mybatis.spring.MyBatisSystemException: nested exception is
严重: Servlet.service() for servlet [appServlet] in context with path [] threw exception [Request proc ...
- 问题集录--JS如何处理和解析Json数据
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.它基于ECMAScript的一个子集. JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族 ...
- javascript高性能
我在<javascript高性能> 这本书里面读到这个文章,所以做一下学习笔记,供大家一块学习: 无阻塞脚本的概念什么? 为什么要用无阻塞脚本? 如何实现无阻塞脚本,和每个实现方式应该注意 ...
- js验证身份证号码是否合规
需求:最近要做实名验证的功能,但是验证身份证号码和身份证图片的接口不想短信,比较贵,所以之前我们要验证严谨一点,参考了网上关于验证身份证号码的代码,总结一下 代码: //验证身份证号码 functio ...
- shell程序设计小知识
一.用户登陆进入系统后的系统环境变量:$HOME 使用者自己的目录$PATH 执行命令时所搜寻的目录$TZ 时区$MAILCHECK 每隔多少秒检查是否有新的信件$PS1 在命令列时的提示号$PS2 ...
- WPF基础控件
1.所有基础控件结束(英文) http://www.dotnetperls.com/tooltip-wpf 2.wpf- DataGrid 常用属性和事件 3.
- 点击checkbox 向input 里面传值显示
文本框显示 <input type="text" id="textareashow" name="" class="marg ...
- IEnumerable Except
// // 摘要: // 通过使用默认的相等比较器对值进行比较生成两个序列的差集. // // 参数: // first: // 一个 System.Collections.Generic.IEnum ...
- SQL语句整理(一) 数据库查询语言DQL
前言: 这是我学数据库时整理的学习资料,基本上包括了所以的SQL语句的知识点. 我的教材是人大王珊老师的<数据库系统概论>. 因为是手打的,所以会用一些细节打错了,但都挺明显也不多(考完试 ...
- 建一个springboot项目
1.打开 https://start.spring.io/ 新建一个maven的demo,这里选择的是1.5.18的版本 2.将自动生成的demo导入eclipse,直接选中File里的import, ...