title: 【CUDA 基础】3.2 理解线程束执行的本质(Part I)

categories:

  • CUDA
  • Freshman

    tags:
  • 线程束分化
  • CUDA分支

    toc: true

    date: 2018-03-14 21:31:16



Abstract: 本文介绍CUDA执行模型最核心的部分,线程束的执行实质第一部分

Keywords: CUDA分支,线程束分化

开篇废话

我们前面已经大概的介绍了CUDA执行模型的大概过程,包括线程网格,线程束,线程间的关系,以及硬件的大概结构,例如SM的大概结构,而对于硬件来说,CUDA执行的实质是线程束的执行,因为硬件根本不知道每个块谁是谁,也不知道先后顺序,硬件(SM)只知道按照机器码跑,而给他什么,先后顺序,这个就是硬件功能设计的直接体现了。

从外表来看,CUDA执行所有的线程,并行的,没有先后次序的,但实际上硬件资源是有限的,不可能同时执行百万个线程,所以从硬件角度来看,物理层面上执行的也只是线程的一部分,而每次执行的这一部分,就是我们前面提到的线程束。

线程束和线程块

线程束是SM中基本的执行单元,当一个网格被启动(网格被启动,等价于一个内核被启动,每个内核对应于自己的网格),网格中包含线程块,线程块被分配到某一个SM上以后,将分为多个线程束,每个线程束一般是32个线程(目前的GPU都是32个线程,但不保证未来还是32个)在一个线程束中,所有线程按照单指令多线程SIMT的方式执行,每一步执行相同的指令,但是处理的数据为私有的数据,下图反应的就是逻辑,实际,和硬件的图形化

线程块是个逻辑产物,因为在计算机里,内存总是一维线性存在的,所以执行起来也是一维的访问线程块中的线程,但是我们在写程序的时候却可以以二维三维的方式进行,原因是方便我们写程序,比如处理图像或者三维的数据,三维块就会变得很直接,很方便。

在块中,每个线程有唯一的编号(可能是个三维的编号),threadIdx。

网格中,每个线程块也有唯一的编号(可能是个三维的编号),blockIdx

那么每个线程就有在网格中的唯一编号。

当一个线程块中有128个线程的时候,其分配到SM上执行时,会分成4个块:

warp0: thread  0,........thread31
warp1: thread 32,........thread63
warp2: thread 64,........thread95
warp3: thread 96,........thread127

当编号使用三维编号时,x位于最内层,y位于中层,z位于最外层,想象下c语言的数组,如果把上面这句话写成c语言,假设三维数组t保存了所有的线程,那么(threadIdx.x,threadIdx.y,threadIdx.z)表示为

t[z][y][x];

计算出三维对应的线性地址是:

tid=threadIdx.x+threadIdx.y×blockDim.x+threadIdx.z×blockDim.x×blockDim.y
tid = threadIdx.x+threadIdx.y\times blockDim.x+threadIdx.z\times blockDim.x \times blockDim.y
tid=threadIdx.x+threadIdx.y×blockDim.x+threadIdx.z×blockDim.x×blockDim.y

上面的公式可以借助c语言的三维数组计算相对地址的方法,如果有人做过图像,或者矩阵,那么这个计算过程应该没啥纠结的。但是对于初学者,这个地方经常性的绕晕,就行我刚开始写图像算法的时候,经常搞不清楚长和宽。

一个线程块包含多少个线程束呢?

WarpsPerBlock=ceil(ThreadsPerBlockwarpSize)
\text{WarpsPerBlock}=\text{ceil}\begin{pmatrix}\frac{\text{ThreadsPerBlock}}{\text{warpSize}}\end{pmatrix}
WarpsPerBlock=ceil(warpSizeThreadsPerBlock​​)

ceil函数是向正无穷取整的函数,比如ceil(98)=2ceil(\frac{9}{8})=2ceil(89​)=2

线程束和线程块,一个是硬件层面的线程集合,一个是逻辑层面的线程集合,我们编程时为了程序正确,必须从逻辑层面计算清楚,但是为了得到更快的程序,硬件层面是我们应该注意的。

线程束分化

完整内容参考https://face2ai.com/CUDA-F-3-2-理解线程束执行的本质-P1/

【CUDA 基础】3.2 理解线程束执行的本质(Part I)的更多相关文章

  1. 【CUDA 基础】5.6 线程束洗牌指令

    title: [CUDA 基础]5.6 线程束洗牌指令 categories: - CUDA - Freshman tags: - 线程束洗牌指令 toc: true date: 2018-06-06 ...

  2. 【CUDA 基础】6.2 并发内核执行

    title: [CUDA 基础]6.2 并发内核执行 categories: - CUDA - Freshman tags: - 流 - 事件 - 深度优先 - 广度优先 - 硬件工作队列 - 默认流 ...

  3. 【CUDA 基础】3.3 并行性表现

    title: [CUDA 基础]3.3 并行性表现 categories: - CUDA - Freshman tags: - nvprof toc: true date: 2018-04-15 21 ...

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

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

  5. 【CUDA 基础】3.1 CUDA执行模型概述

    title: [CUDA 基础]3.1 CUDA执行模型概述 categories: CUDA Freshman tags: CUDA SM SIMT SIMD Fermi Kepler toc: t ...

  6. 【CUDA 基础】2.3 组织并行线程

    title: [CUDA 基础]2.3 组织并行线程 categories: CUDA Freshman tags: Thread Block Grid toc: true date: 2018-03 ...

  7. 前端知识体系:JavaScript基础-原型和原型链-理解JavaScript的执行上下文栈,可以应用堆栈信息快速定位问题

    理解JavaScript的执行上下文栈,可以应用堆栈信息快速定位问题(原文文档) 1.什么是执行上下文: 简而言之,执行上下文就是当前JavaScript代码被解析和执行时所在环境的抽象概念,Java ...

  8. 【CUDA 基础】6.3 重叠内和执行和数据传输

    title: [CUDA 基础]6.3 重叠内和执行和数据传输 categories: - CUDA - Freshman tags: - 深度优先 - 广度优先 toc: true date: 20 ...

  9. 【CUDA 基础】5.2 共享内存的数据布局

    title: [CUDA 基础]5.2 共享内存的数据布局 categories: - CUDA - Freshman tags: - 行主序 - 列主序 toc: true date: 2018-0 ...

随机推荐

  1. nodejs+gulp+webpack基础知识

    nodejs+gulp+webpack基础知识 2019年08月22日 11:49:40 天府云创 阅读数 22   版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文 ...

  2. 怎样理解HTMLCollection接口

    和 NodeList 类似, HTMLCollection 也是一个 类数组对象, 和NodeList不同的是, 它是各种 元素节点 的集合, 且不具有 forEach() 方法, 因此如果不转为真正 ...

  3. kali入侵服务器之后清除痕迹

    Linux清除痕迹 第一种方法: 在退出会话前直接执行: #history -r 清除当前会话的命令历史记录 第二种方法: 在vim中执行自己不想让别人看到的命令随便用vim打开一个文件 :set h ...

  4. sass之mixin的全局引入(vue3.0)

    sass之mixin的全局引入(vue3.0) 1.scss文件(mixin.scss) /* 渐变 */ @mixin gradual($color, $color1){ background: $ ...

  5. javascript是一种安全语言

    一.简单JavaScript是一个基于Java基本语句和控制流的简单而紧凑的设计,这是学习Java的一个很好的过渡.它的变量类型是弱类型,而不是严格的数据类型.二.力学JavaScript是动态的,可 ...

  6. jQuery EasyUI中DataGird动态生成列的方法

    EasyUI中使用DataGird显示数据列表中,有时需要根据需要显示不同的列,例如,在权限管理中,不同的用户登录后只能查看自己权限范围内的列表字段,这就需要DataGird动态组合列,下面介绍Eas ...

  7. kbmMW 5.09.00是个必须升级的版本!

    这几天遇到的几个问题,从5.08.10升级到5.09.00,自然解决了! 所以建议大家都升级到这个版本. 例如我遇到的问题: 1.在线程中使用ClientQuery注意的问题 2.Invalid pr ...

  8. C# 字符串拼接性能探索 c#中+、string.Concat、string.Format、StringBuilder.Append四种方式进行字符串拼接时的性能

    本文通过ANTS Memory Profiler工具探索c#中+.string.Concat.string.Format.StringBuilder.Append四种方式进行字符串拼接时的性能. 本文 ...

  9. python中F/f表达式优于format()表达式

    F/f表达式可以解析任意类型的数据 具体实现,看下面示例: 1.解析变量 1 a = 10 3 b = 20 5 res1 = F"a+b的值:{a+b}" 7 print(res ...

  10. 【异常】Phoenix异常:java.lang.ArithmeticException: Rounding necessary

    1 异常sql upsert into WMBIGDATA.ODS_ES_CHARGING_STATION(id,evcosType,address,serviceTel,supportOrder,o ...