Udacity并行计算课程笔记-The GPU Hardware and Parallel Communication Patterns
本小节笔记大纲:
- 1.Communication patterns
- gather,scatter,stencil,transpose
- 2.GPU hardware & Programming Model
- SMs,threads,blocks,ordering
- Synchronization
- Memory model: local, shared, global
- Atomic Operation
- 3.Efficient GPU Programming
- Access memory faster
- coalescing global memory
- use faster memory
- Avoid thread divergence
- Access memory faster
一、Communication Patterns
1.Patterns
- Map
map很好理解,其实就是映射,也就是输入和输出一一对应,一个萝卜一个坑
- Gather
Gather中文名为收集,是将若干个输入数据经过计算后得到一个输出值,如图左示。很典型的应用就是比如说对于一个图像,我们需要每一个像素值是其四周像素的平均值。
- Scatter
scatter的特点是每个线程一次会向内存输出多个值,也可能多个线程向一个内存输出值。
- Stencil
Stencil表示模板的意思,所以也就是计算的时候用模子来选择输入数据,看下图就清楚了
- Transpose
其实就是转置啦~
具体应用实例如下:
在C语言中,加入我们定义了如上图示的一个结构体,包含float和int两种变量,然后我们又定义了一个该结构体的变量数组,一般来说其在内存中是像上面那样排列的,强迫症看起来是不是不舒服,而且这种排列方式比较浪费空间,所以通过转置后形成下面的排列方式后既美观又使运算加速了,岂不美哉?
2.练习题
- 第一个很简单就是map,不仔细解释了
- 第二个个表达式我之前脑袋一热就选了C。。但是要注意,scatter的特点是每个线程一次会向内存输出多个值,这显然不符合该特点,而应该是Transpose。
- 第三个就是scatter了,原因如上
- 最后一个很容易选stencil,但是你要注意if条件语句的限制,所以应该是Gather。
3.总结神图
二、GPU Hardware
1.问题导向
- 线程是如何有效地一致访问内存
- 子话题:如何利用数据重用
- 线程如何通过共享内存通信部分结果
2.硬件组成
如图示,GPU由若干个SM(Stream Multiprocessor流多处理器)组成,而每个SM又包含若干个SP(教材上是Stream Processor流处理器,改视频中是simple processor),anyway...开心就好,管他叫什么名字~
GPU的作用是负责分配线程块在硬件SM上运行,所有SM都以并行独立的方式运行。
下面做一下题目吧:
解析:
- 1正确.一个线程块包含许多线程
- 2正确.一个SM可能会运行多个多个线程块
- 3错误,因为一个线程块无法在一个以上的SM上运行
- 4正确,在一个线程块上所有线程有可能配合起来解决某个子问题
- 5错误,一个SM上可能有多个线程块,但是根据定义,线程和不同的线程块不应该存在协作关系。
3.程序员与GPU分工
另外需要注意的是程序员负责定义线程块,而GPU则负责管理硬件,因此程序员不能指定线程块的执行顺序,也不能指定线程块在某一特定的
SM上运行。
这样设计的好处如下:
- 硬件可以运行的更加有效率
- 运行切换不需要等待,一旦一个线程块运行完毕,SM可以自动的将另一个线程块加载进来
- 最大的优势:可扩展性,因为可以自动分配硬件资源,所以向下到单个SM,上到超级计算机的大量SM,均可以很好的适应。
有如上好处的同时,自然也就有局限性:
- 对于哪个块在哪个SM上运行无法进行任何假设
- 无法获得块之间的明确的通信
4.GPU Memory Model
如图示
- 每个线程都有它自己的本地内存(local memory)
- 线程块有一个共享内存(shared memory),块中所有线程都可以访问该内存中的数据
- GPU中的全局内存(global memory)是所有线程块中的线程都能访问的内存,也是CPU进行数据传递的地方。
访问速度:
local memory > shared memory > global
例题:
解析:
s,t,u是本地内存中的变量,所以t=s最先运行,同理可以排除其他代码运行顺序。
注意:这只是为了说明访问速度出的例题,实际情况中,编译器可能会做出相应的调整来达到我们的目的
5.Sychronization
说道线程,很自然我们就需要考虑同步。GPU中的同步有如下几种:
Barrier(屏障)
顾名思义,就是所有线程运行到这个点都需要停下来。
如图示,红色、蓝色、绿色代表的线程先后到达barrier这个时间点后都停下来进行同步操作,完成之后线程的执行顺序是不一定的,可能如图示蓝色线程先执行,绿色,红色紧随其后。
另外其实还有一种隐式的barrier,比如说先后启动kernel A和kernel B,一般来说kernel B执行之前kernel A肯定是执行完毕了的。
说了这么多来做下题吧~233
题目:如下图示,现在需要实现一个数组前移的操作,即后面一个往前面挪,共享数组大小是128,问为实现这个功能,需要设置几次同步操作(或者说需要设置几个barrier?)
解析:
最开始的时候没想明白,写了127,128,但是都不对。后来听解释才明白。前移操作可以分为三步:
- 为每个数组元素赋值,即
array[idx] = threadIdx.x;
__syncthreads(); # 128个线程都执行完赋值语句后才能进行下一步
- 读取后面一个元素的值,存在临时变量里
int temp = array[idx+1];
__syncthreads();
- 将后一元素的值往前移
array[idx] = temp;
__syncthreads();
6.Atomic Memory Operation
在cuda编程中经常会碰到这样的情况,即大量的线程同时都需要对某一个内存地址进行读写操作,很自然这会发生冲突,如下图示:
下面是发生冲突的具体的代码示例:
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <stdio.h>#define NUM_THREADS 10000
#define ARRAY_SIZE 10
#define BLOCK_WIDTH 100void printDevice();__global__ void increment_naive(int *g)
{int i = blockIdx.x * blockDim.x + threadIdx.x;i = i % ARRAY_SIZE;g[i] = g[i] + 1;
}int main(int argc, char **argv)
{printDevice();printf("\n");int h_array[ARRAY_SIZE];const int ARRAY_BYTES = ARRAY_SIZE * sizeof(int);int *d_array;// 分配内存cudaMalloc((void **) &d_array, ARRAY_BYTES);cudaMemset((void *) d_array, 0, ARRAY_BYTES);increment_naive<<<NUM_THREADS/BLOCK_WIDTH, BLOCK_WIDTH>>>(d_array);cudaMemcpy(h_array, d_array, ARRAY_BYTES, cudaMemcpyDeviceToHost);for(int i=0; i<ARRAY_SIZE; i++){printf("%d:%d\n",i,h_array[i]);}// 释放内存cudaFree(d_array);getchar();//CUDA_SAFE_CALL(cudaGetDeviceCount(&deviceCount));return 0;
}
运行结果:(每次运行的结果是不确定的)
这里就需要引入原子操作,只需要将读写函数进行如下修改
__global__ void increment_atomicNaive(int *g)
{int i = blockIdx.x * blockDim.x + threadIdx.x;i = i % ARRAY_SIZE;atomicAdd(&g[i], 1);
}
运行结果:
使用原子操作也是有一定限制的,如下:
- 只能使用一些特定的运算(如加、减、最小值、异或等运算,但是取模,求幂等运算则不行)和数据类型(一般是整型int)
- 每个线程块里的不同线程以及线程块本身将以不定的顺序运行,我们在内存上用原子进行的运算顺序也是不定的。
例如下面的计算表达式的记过会不一样:
\(a+b+c 和 a+(b+c),其中a=1,b=10^,c=-10^{99}\) - 虽然顺序不确定,但是要知道的是GPU还是会强制每个线程轮流访问内存,这把不同线程对内存的访问串行化
提高CUDA编程效率策略
- 高运算密度(high arithmetic intensity)
\(\frac{math}{memory}\)
前面提到了很多优化策略是集中在memory上的,把数据尽可能放到更快地内存上去,其中内存速度是
local > share > global
- 避免线程发散(avoid thread divergence)
如图是线程发散的主要场景,即if else语句,上图右边非常生动的展现了线程发散的情形,可以看到各个线程在碰到if条件句后开始发散,最后聚合,但是最后各个线程之间的编号还是保持原来的不变的,这就是线程发散。
下面举一个更加极端的例子,就是循环语句,如下图示:
可以看到有蓝、红、绿、紫四个线程同时运行,蓝线程只循环了一次,其他线程循环次数都多于蓝线程,当蓝线程退出循环后就不得不一直等着其他线程,上图左下角的示意图可以很直观的看到这大大降低了运行效率,这也是为什么我们需要避免线程发散。
Summary
MARSGGBO原创
2017-11-1
Udacity并行计算课程笔记-The GPU Hardware and Parallel Communication Patterns相关推荐
- Lesson 2 - GPU Hardware and Parallel Communication Patterns
目录 1.Welcome to Unit2 2.Communication Patterns 3.Map and Gathre 4.练习:Scatter 5.练习:Stencil 6.Transpos ...
- 西电李航 操作系统课程笔记 day10 IO hardware principles
文章目录 Principles of IO hardware IO设备 块设备(block device) 字符设备(character device) 设备控制器(device controller ...
- Udacity机器人软件工程师课程笔记(五)-样本搜索和找回-基于漫游者号模拟器-自主驾驶
9.自主驾驶 在接下来的环节中,我们要实现漫游者号的自动驾驶功能. 完成这个功能我们需要四个程序,第一个为感知程序,其对摄像头输入的图片进行变换处理和坐标变换使用.第二个程序为决策程序,功能是帮助漫游 ...
- 【CS231n 课程笔记】第八讲-----常见的深度学习框架,以及GPU和CPU介绍。
目录 0.写在前面 1.CPU VS GPU 1.1GPU 与CPU的比较 1.2性能测试 1.3实践中的问题 2.深度学习框架 2.1 计算图思想和深度学习框架 2.2 tensorflow 2.2 ...
- Udacity无人驾驶工程师课程笔记:1 计算机视觉基础——基于Hough变换的车道线提取
Udacity无人驾驶工程师课程笔记:1 计算机视觉基础--基于Hough变换的车道线提取 图像处理 颜色选择 区域遮罩 组合颜色和区域选择 边缘检测 Canny边缘检测 Hough变换 Hough变 ...
- 《区块链技术与应用》北大肖臻老师——课程笔记【6-8】
<区块链技术与应用>北大肖臻老师--课程笔记[6-8] 一.BTC网络 二.BTC-挖矿难度 三.BTC-挖矿 提示:以下内容只是个人在学习过程中记录的笔记,图片均是肖老师课程的截图,可供 ...
- 这份深度学习课程笔记获吴恩达点赞
来源:机器之心 本文共7470字,建议阅读8分钟. 通过本文用优美的信息图为大家解读深度学习课程的知识与亮点~ 吴恩达在推特上展示了一份由 TessFerrandez 完成的深度学习专项课程信息图,这 ...
- 超级干货丨优美的课程笔记,吴恩达点赞的深度学习课程信息图
吴恩达在推特上展示了一份由 TessFerrandez 完成的深度学习专项课程信息图,这套信息图优美地记录了深度学习课程的知识与亮点.因此它不仅仅适合初学者了解深度学习,还适合机器学习从业者和研究者复 ...
- Coursera吴恩达《优化深度神经网络》课程笔记(1)-- 深度学习的实用层面
红色石头的个人网站:redstonewill.com Andrew Ng的深度学习专项课程的第一门课<Neural Networks and Deep Learning>的5份笔记我已经整 ...
最新文章
- JAVA必备——13个核心规范
- hive(让我凌乱的一天)
- 【JOURNAL】911的虚惊
- springboot webservice接口调用_springboot远程调用dubbo服务接口
- 《架构系列四:一键部署应用到Tomcat集群中》
- [嵌入式]I2C协议指东
- 疯狂Java讲义(读书笔记)(第六章--Java基础类库)
- 近远场转换算法matlab,计算电磁学之FDTD算法的MATLAB语言实现解析.doc
- 关于在android平台使用nanohttpd实现的http服务在WIFI环境下响应明显太慢的问题
- GPS开发、定位修改
- 硬盘播放器和pc计算机,电脑可不可以用来当电影播放器用
- whois信息收集企业备案信息
- LaTex Introduction 基础介绍
- 亚马逊云EC2助力5G产品测试
- 小程序入口构造工具二维码测试工具
- 基于DINet的虚拟数字人
- 程序员必备的8个编程工具
- 微信手环1年多了,前主管终于出来聊了聊它是怎么诞生的
- [Unity] 制作游戏 赛车小游戏
- Unity UGUI图集专题
热门文章
- java.sql.sqlexception: 无效的名称模式:_PSQLException:错误:关系&ldquo; TABLE_NAME&rdquo;不存在...
- 河北职称计算机2012试题,2012年河北省职称计算机考试试题及答案.doc
- vmware虚拟机迁移到hyperv_ProxmoxVE 之 V2V迁移(vmware-PVE)
- python数据特征提取_训练数据的特征提取
- mysql创建反弹函数,MySql创建函数
- python-tkinter模块图形分布移动(可键盘操作)
- 【周报6.10-6.16】NLP,RL,GAN,DL框架等重磅专栏齐上线,这个月的有三AI你值得拥有...
- 全球与中国太赫兹安检仪市场竞争状况及未来发展趋向分析报告2022-2028年版
- 中国抛光打磨机器人行业发展方向分析与十四五战略规划研究报告2022年版
- 微量元素重塑新生态-农业大健康·李喜贵:谋定功能性农业