网格(Grid)、线程块(Block)和线程(Thread)的组织关系


CUDA的软件架构由网格(Grid)、线程块(Block)和线程(Thread)组成,相当于把GPU上的计算单元分为若干(2~3)个网格,每个网格内包含若干(65535)个线程块,每个线程块包含若干(512)个线程,三者的关系如下图:

Thread,block,grid是CUDA编程上的概念,为了方便程序员软件设计,组织线程。

  • thread:一个CUDA的并行程序会被以许多个threads来执行。
  • block:数个threads会被群组成一个block,同一个block中的threads可以同步,也可以通过shared memory通信。
  • grid:多个blocks则会再构成grid。

网格(Grid)、线程块(Block)和线程(Thread)的最大数量


CUDA中可以创建的网格数量跟GPU的计算能力有关,可创建的Grid、Block和Thread的最大数量参看以下表格:



在单一维度上,程序的执行可以由多达3*65535*512=100661760(一亿)个线程并行执行,这对在CPU上创建并行线程来说是不可想象的。

线程索引的计算公式


一个Grid可以包含多个Blocks,Blocks的组织方式可以是一维的,二维或者三维的。block包含多个Threads,这些Threads的组织方式也可以是一维,二维或者三维的。
CUDA中每一个线程都有一个唯一的标识ID—ThreadIdx,这个ID随着Grid和Block的划分方式的不同而变化,这里给出Grid和Block不同划分方式下线程索引ID的计算公式。

1、 grid划分成1维,block划分为1维


    int threadId = blockIdx.x *blockDim.x + threadIdx.x;  

    

  
2、 grid划分成1维,block划分为2维  

    int threadId = blockIdx.x * blockDim.x * blockDim.y+ threadIdx.y * blockDim.x + threadIdx.x;  

  

  
3、 grid划分成1维,block划分为3维  

    int threadId = blockIdx.x * blockDim.x * blockDim.y * blockDim.z  

                       + threadIdx.z * blockDim.y * blockDim.x  

                       + threadIdx.y * blockDim.x + threadIdx.x;  


  
4、 grid划分成2维,block划分为1维  

    int blockId = blockIdx.y * gridDim.x + blockIdx.x;  

    int threadId = blockId * blockDim.x + threadIdx.x;  

   

  
5、 grid划分成2维,block划分为2维 

    int blockId = blockIdx.x + blockIdx.y * gridDim.x;  

    int threadId = blockId * (blockDim.x * blockDim.y)  

                       + (threadIdx.y * blockDim.x) + threadIdx.x;  

    

  
6、 grid划分成2维,block划分为3维

    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;  

   

  
7、 grid划分成3维,block划分为1维 

    int blockId = blockIdx.x + blockIdx.y * gridDim.x  

                     + gridDim.x * gridDim.y * blockIdx.z;  

    int threadId = blockId * blockDim.x + threadIdx.x;  

   

  
8、 grid划分成3维,block划分为2维  

    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;  

   

  
9、 grid划分成3维,block划分为3维

    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;     

CUDA软件架构—网格(Grid)、线程块(Block)和线程(Thread)的组织关系以及线程索引的计算公式的更多相关文章

  1. CUDA学习(六)之使用共享内存(shared memory)进行归约求和(M个包含N个线程的线程块)

    在https://www.cnblogs.com/xiaoxiaoyibu/p/11402607.html中介绍了使用一个包含N个线程的线程块和共享内存进行数组归约求和, 基本思路: 定义M个包含N个 ...

  2. 【并行计算-CUDA开发】CUDA线程、线程块、线程束、流多处理器、流处理器、网格概念的深入理解

    GPU的硬件结构,也不是具体的硬件结构,就是与CUDA相关的几个概念:thread,block,grid,warp,sp,sm. sp: 最基本的处理单元,streaming processor  最 ...

  3. cuda线程/线程块索引小结

    内建变量: threadIdx(.x/.y/.z代表几维索引):线程所在block中各个维度上的线程号 blockIdx(.x/.y/.z代表几维索引):块所在grid中各个维度上的块号 blockD ...

  4. 《GPU高性能编程CUDA实战》第四章 简单的线程块并行

    ▶ 本章介绍了线程块并行,并给出两个例子:长向量加法和绘制julia集. ● 长向量加法,中规中矩的GPU加法,包含申请内存和显存,赋值,显存传入,计算,显存传出,处理结果,清理内存和显存.用到了 t ...

  5. CUDA学习(四)之使用全局内存进行归约求和(一个包含N个线程的线程块)

    问题:使用CUDA进行数组元素归约求和,归约求和的思想是每次循环取半. 详细过程如下: 假设有一个包含8个元素的数组,索引下标从0到7,现通过3次循环相加得到这8个元素的和,使用一个间隔变量,该间隔变 ...

  6. CUDA学习(五)之使用共享内存(shared memory)进行归约求和(一个包含N个线程的线程块)

    共享内存(shared memory)是位于SM上的on-chip(片上)一块内存,每个SM都有,就是内存比较小,早期的GPU只有16K(16384),现在生产的GPU一般都是48K(49152). ...

  7. CUDA 关于 BLOCK数目与Thread数目设置

    GPU的计算核心是以一定数量的Streaming Processor(SP)组成的处理器阵列,NV称之为Texture Processing Clusters(TPC),每个TPC中又包含一定数量的S ...

  8. Objective-C-----协议protocol,代码块block,分类category

    概述 ObjC的语法主要基于smalltalk进行设计的,除了提供常规的面向对象特性外,还增加了很多其他特性,本文将重点介绍objective-C中一些常用的语法特性. 当然这些内容虽然和其他高级语言 ...

  9. Django---MTV和MVC的了解,Django的模版语言变量和逻辑,常见的模板语言过滤器,自定义过滤器,CSRF了解,Django的母版(继承extends,块block,组件include,静态文件的加载load static),自定义simple_tag和inclusion_tag

    Django---MTV和MVC的了解,Django的模版语言变量和逻辑,常见的模板语言过滤器,自定义过滤器,CSRF了解,Django的母版(继承extends,块block,组件include,静 ...

随机推荐

  1. MySQL參数binlog-do-db对binlogs写入的影响

    1. 环境描写叙述 目的:当数据库中设置了binlog-do-db时.在不同的binlog_format=statement | row | mixed 下对binlog的写入影响,这个在主从复制中会 ...

  2. linux查找keyword在php出现的次数

    查找CleverCode在当前文件夹以及子文件夹,全部的php出现大于0的次数. # find -type f -name '*.php' | xargs grep CleverCode ./*.ph ...

  3. C语言深度剖析-----数组参数和指针参数分析

    数组退化的意义 当向函数传递数组时, 二维数组参数 等价关系 注意事项 只能去一维数组 无法向一个函数传递一个任意的多维数组,注释地方出错 传递与访问二维数组的方式 动态地算出二维数组的列

  4. eclipse在线安装超级炫酷黑色主题

    Darkest Dark Theme插件: 点击菜单栏 Help --> Eclipse Marketplace,输出Darkest Dark Theme进行搜索,如下图: 本主题有17套编辑器 ...

  5. Java反射学习总结四(动态代理使用实例和内部原理解析)

    通过上一篇文章介绍的静态代理Java反射学习总结三(静态代理)中,大家可以发现在静态代理中每一个代理类只能为一个接口服务,这样一来必然会产生过多的代理,而且对于每个实例,如果需要添加不同代理就要去添加 ...

  6. h5 video 点击自动全屏

    加上如下属性 https://blog.csdn.net/weixin_40974504/article/details/79639478 可阻止自动全屏播放,感谢 https://blog.csdn ...

  7. [Recompose] Flatten a Prop using Recompose

    Learn how to use the ‘flattenProp’ higher order component to take a single object prop and spread ea ...

  8. 多线程之线程通信条件Condition二

    接上一篇,实现Condition三个条件,有这样一个应用: 1. 有三个进程,第一个进程运行1次,第二个进程运行2次,第三个进程运行3次: 2. 先运行第二个进程,然后第一个,然后第三个: 3.  依 ...

  9. ios开发网络学习AFN三:AFN的序列化

    #import "ViewController.h" #import "AFNetworking.h" @interface ViewController () ...

  10. 有关下拉列表、复选框、单选按钮、iframe等jquery处理方法

    1.jquery验证复选框互斥选项,代码如下: //验证复选框中的互斥选项 function checkData(name, val1, val2){ //获取所有checkbox值 var chec ...