CUDA编程之GPU硬件架构
GPU的硬件架构
GPU的整体架构图
GPU实际上是一个流处理器簇 Streaming Multiprocessors(SM)的阵列。如下图所示:
GPU(G80/GT200)卡的组成模块图
需要指出,每个
SM
包含的SP
数量依据GPU架构而不同,Fermi架构GF100是32个,GF10X是48个,Kepler架构都是192个,Maxwell都是128个。相同架构的GPU包含的SM数量则根据GPU的中高低端来决定。
流处理器簇结构
每个SM(streaming multiprocessor)由以下部分组成:
- CUDA Cores(CUDA核,也常称作SP(streaming processor))
- Shared Memory/L1 Cache (共享内存/L1缓存)
- Register File (寄存器文件)
- Load/Store Units (加载存储单元)
- Special Function Units (特殊功能单位)
- Warp Scheduler(Warp调度器)
SM基本架构
GPU中的每个SM
都支持数百个线程的并发执行,通常是每个GPU有多个SM
,所以有可能有数千个线程并发执行。CUDA采用了SIMT
单指令多线程执行,一个指令32个线程执行,32个线程组织成warp
。一个warp
中的线程同一时刻执行同一个指令。每个线程有自己的指令技术计数器和寄存器,在自己的数据上执行指令。
warp:GPU执行程序时的调度单位,目前cuda的warp的大小为32,同在一个warp的线程,以不同数据资源执行相同的指令,这就是所谓 SIMT。
Warp的执行方式
当创建了一个kernel时,从逻辑上理解为kernel中的所有线程都在并行,但是从硬件物理条件上看同一时刻并不是所有的线程都在执行。因此Warp概念的提出,主要是将软件上并行的线程与硬件的实际架构连接起来。如下图所示:
Warp连接软硬件
warp是SM上的基本执行单元。当一个线程块分配到一个SM上时,线程块被组织成warps,SM上的warp调度器选择合适的warp执行。
warp执行示意图
warp一定是同一个block中的,如果一个block中的threads不足32个,则补足成为32个构成一个warp。
如图所示,本来只需要80个线程,但是实际上仍然需要32*3=96个threads,尽管最后一个warp的16个线程没有使用,但是仍然会消耗SM上的资源,比如共享存储器、寄存器。
Warp分支
定义:一个warp中的线程执行不同的指令,叫做warp分支。 如果warp发生分支,则需要顺序执行每个分支路径。
warp分支示意图
在一个warp中所有线程都必须具有两个分支if…else….一个warp中如果有线程的条件为true,则执行if子句,其它为false的线程将等待if执行完成。然后执行else语句,当条件为true的线程则等待else执行完成。 为了获得更高的性能,尽量避免warp分支,warp是32个连续的线程,在算法允许的情况下,可以将数据分割,使同一个warp避免分支。
软件与硬件并行对比
软硬件对比图
通过上图可以看出,一个网格相当于一个GPU设备,网格下分成多个线程块,线程块则对应的SM,每个线程块又分为多个线程,每个线程相当于一个CUDA核。
参考
CUDA编程指南3.0 [【CUDA】学习记录(3)-硬件结构]https://www.jianshu.com/p/2fbd02311266
- 系列3|走进Node.js之多进程模型
- Java中Arraylist与linkedlist的区别
- 手把手教你撸一个 Webpack Loader
- HashMap与HashTable区别
- iKcamp|基于Koa2搭建Node.js实战(含视频)☞ 记录日志
- React Native 网络层分析
- 如何实现VM框架中的数据绑定
- Java盲点解析
- iKcamp|基于Koa2搭建Node.js实战(含视频)☞ 解析JSON
- iKcamp|基于Koa2搭建Node.js实战(含视频)☞ 处理静态资源
- iKcamp|基于Koa2搭建Node.js实战(含视频)☞ 视图Nunjucks
- iKcamp|基于Koa2搭建Node.js实战(含视频)☞ 代码分层
- iKcamp|基于Koa2搭建Node.js实战(含视频)☞ HTTP请求
- ubuntu中安装tomcat
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法