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 ...
随机推荐
- JVM(三) 垃圾回收时间点和垃圾收集器
收集器组合章节来自第一篇参考文章,非原创,作者总结地非常好! 分代收集相关概念来自参考文章第二篇,非原创 第二篇参考资料的文章质量很高,推荐阅读! 分代收集(Ge ...
- 手机UA识别
整理手机UA识别如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset=&qu ...
- [javaEE] javaweb的mvc设计思想
Servlet:在Servlet中拼接html内容 JSP:在html中拼接java JSP+JavaBean:利用javaBean将大量的代码提取走 Servlet+JSP+JavaBean:Ser ...
- [android] 通过比对进行容器联动
当中间容器变化之后,标题栏也要跟着变化 设计个比对依据: 抽象类BaseView中定义抽象方法,每个继承的View都必须实现,为自己的界面定义一个唯一的int常量,作为比对依据 降低容器之间的耦合度: ...
- log4j的简单使用
引入jar包org.apache.log4j.Logger,项目src目录下建立一个log4j.properties配置文件 log4j.rootLogger=INFO,A1,R log4j.appe ...
- spring 代理
java动态代理实现 1. Java自带的动态代理,反射生成字节码 2. Cglib调用asm生成子类 spring 中代理实现 1. 如果类实现了接口,使用java动态代理 2. 没有实现接口,使用 ...
- Selector#wakeup()
看thrift源码发现selector.wakeup()方法,通常在selector.select()后线程会阻塞.使用wakeup()方法,线程会立即返回.源码分析应该是用的线程中断实现的.下面是个 ...
- lintcode 题目记录3
Expression Expand Word Break II Partition Equal Subset Sum Expression Expand 字符串展开问题,按照[]前的数字展开字符 ...
- nginx服务器绑定多个域名、支持pathinfo路由、隐藏index.php入口文件
这篇文章仅仅是操作,解释说明部分待更新. 1. 修改nginx的配置文件(我的配置文件在/etc/nginx/nginx.conf) [root@xxx ~]# find / -name nginx. ...
- Codeforces Round #394 (Div. 2)
前一半是刚刚打完比赛的时候写的……不知为啥手腕有点僵,估计是前一个小时用力过度了吧= = 前四题看着还好,后两题就有点懵逼了……现在还不知道E题的题意到底是啥…… 不管了……还没找着官方题解,贴一下自 ...