【CUDA 基础】3.6 动态并行
title: 【CUDA 基础】3.6 动态并行
categories:
- CUDA
- Freshman
tags:
- 动态并行
- 嵌套执行
- 隐式同步
toc: true
date: 2018-04-24 20:57:48

Abstract: 本文介绍CUDA动态并行——在设备上运行时的网格启动新的子网格
Keywords: 动态并行,嵌套执行
动态并行
本文作为第三章CUDA执行模型的最后一篇介绍动态并行,书中关于动态并行有一部分嵌套归约的例子,但是我认为,这个例子应该对我们用途不大,首先它并不能降低代码复杂度,其次,其运行效率也没有提高,动态并行,相当于串行编程的中的递归调用,递归调用如果能转换成迭代循环,一般为了效率的时候是要转换成循环的,只有当效率不是那么重要,而更注重代码的简洁性的时候,我们才会使用,所以我们本文只介绍简单的一些基础知识,如果需要使用动态并行相关内容的同学,请查询文档或更专业的博客。
到目前为止,我们所有的内核都是在主机线程中调用的,那么我们肯定会想,是否我们可以在内核中调用内核,这个内核可以是别的内核,也可以是自己,那么我们就需要动态并行了,这个功能在早期的设备上是不支持的。
动态并行的好处之一就是能让复杂的内核变得有层次,坏处就是写出来的程序更复杂,因为并行行为本来就不好控制,去年我在没有系统的学习CUDA的时候写过一个400行左右的内核,用来训练人脸检测程序,确实比cpu块,但是从gpu的温度来判断,并没有很高的利用率(当时还不会使用性能检测工具这些,当时TensorFlow跑的时候GPU温度有80多,但是我写的就只有60多,所以我断定,gpu性能完全没发挥,但是那个程序还是运行了好久,可见磨刀不误砍柴工这句话是多么正确)
动态并行的另一个好处是等到执行的时候再配置创建多少个网格,多少个块,这样就可以动态的利用GPU硬件调度器和加载平衡器了,通过动态调整,来适应负载。并且在内核中启动内核可以减少一部分数据传输消耗。
嵌套执行
前面我们大费周章的其实也就只学了,网格,块,和启动配置,以及一些线程束的知识,现在我们要做的是从内核中启动内核。
内核中启动内核,和cpu并行中有一个相似的概念,就是父线程和子线程。子线程由父线程启动,但是到了GPU,这类名词相对多了些,比如父网格,父线程块,父线程,对应的子网格,子线程块,子线程。子网格被父线程启动,且必须在对应的父线程,父线程块,父网格结束之前结束。所有的子网格结束后,父线程,父线程块,父网格才会结束。

上图清晰地表明了父网格和子网格的使用情况,一种典型的执行方式:
主机启动一个网格(也就是一个内核)-> 此网格(父网格)在执行的过程中启动新的网格(子网格们)->所有子网格们都运行结束后-> 父网格才能结束,否则要等待
如果调用的线程没有显示同步启动子网格,那么运行时保证,父网格和子网格隐式同步。
图中显式的同步了父网格和子网格,通过设置栅栏的方法。
父网格中的不同线程启动的不同子网格,这些子网格拥有相同的父线程块,他们之间是可以同步的。线程块中所有的线程创建的所有子网格完成之后,线程块执行才会完成。如果块中的所有线程在子网格完成前退出,那么子网格隐式同步会被触发。隐式同步就是虽然没用同步指令,但是父线程块中虽然所有线程都执行完毕,但是依旧要等待对应的所有子网格执行完毕,然后才能退出。
前面我们讲过隐式同步,比如cudaMemcpy就能起到隐式同步的作用,但是主机内启动的网格,如果没有显式同步,也没有隐式同步指令,那么cpu线程很有可能就真的退出了,而你的gpu程序可能还在运行,这样就非常尴尬了。父线程块启动子网格需要显示的同步,也就是说不通的线程束需要都执行到子网格调用那一句,这个线程块内的所有子网格才能依据所在线程束的执行,一次执行。
接着是最头疼的内存,内存竞争对于普通并行就很麻烦了,现在对于动态并行,更麻烦,主要的有下面几点:
- 父网格和子网格共享相同的全局和常量内存。
- 父网格子网格有不同的局部内存
- 有了子网格和父网格间的弱一致性作为保证,父网格和子网格可以对全局内存并发存取。
- 有两个时刻父网格和子网格所见内存一致:子网格启动的时候,子网格结束的时候
- 共享内存和局部内存分别对于线程块和线程来说是私有的
- 局部内存对线程私有,对外不可见。
在GPU上嵌套Hello World
完整内容参考https://face2ai.com/CUDA-F-3-6-动态并行/
【CUDA 基础】3.6 动态并行的更多相关文章
- 【CUDA 基础】2.3 组织并行线程
title: [CUDA 基础]2.3 组织并行线程 categories: CUDA Freshman tags: Thread Block Grid toc: true date: 2018-03 ...
- CUDA基础介绍
一.GPU简介 1985年8月20日ATi公司成立,同年10月ATi使用ASIC技术开发出了第一款图形芯片和图形卡,1992年4月ATi发布了Mach32图形卡集成了图形加速功能,1998年4月ATi ...
- 【CUDA 基础】5.2 共享内存的数据布局
title: [CUDA 基础]5.2 共享内存的数据布局 categories: - CUDA - Freshman tags: - 行主序 - 列主序 toc: true date: 2018-0 ...
- 【CUDA 基础】6.1 流和事件概述
title: [CUDA 基础]6.1 流和事件概述 categories: - CUDA - Freshman tags: - 流 - 事件 toc: true date: 2018-06-10 2 ...
- 【CUDA 基础】6.0 流和并发
title: [CUDA 基础]6.0 流和并发 categories: - CUDA - Freshman tags: - 流 - 事件 - 网格级并行 - 同步机制 - NVVP toc: tru ...
- 【CUDA 基础】5.3 减少全局内存访问
title: [CUDA 基础]5.3 减少全局内存访问 categories: - CUDA - Freshman tags: - 共享内存 - 归约 toc: true date: 2018-06 ...
- 【CUDA 基础】4.4 核函数可达到的带宽
title: [CUDA 基础]4.4 核函数可达到的带宽 categories: - CUDA - Freshman tags: - 带宽 - 吞吐量 - 矩阵转置 toc: true date: ...
- 【CUDA 基础】4.1 内存模型概述
title: [CUDA 基础]4.1 内存模型概述 categories: - CUDA - Freshman tags: - CUDA内存模型 - CUDA内存层次结构 - 寄存器 - 共享内存 ...
- 【CUDA 基础】3.4 避免分支分化
- title: [CUDA 基础]3.4 避免分支分化 categories: - CUDA - Freshman tags: - 规约问题 - 分支分化 toc: true date: 2018- ...
随机推荐
- js gridview中checkbox的全选与全不选
1.html: <asp:GridView runat="server" ID="gvAddBySR" AutoGenerateColumns=" ...
- MVC4中去掉浏览器生成的无关代码方法
通过增加Web.Config配置,如: <add key="vs:EnableBrowserLink" value="false"/>可以去掉MVC ...
- js之运算符(关系运算符)
关系运算符用于测试两个值之间的关系,根据关系是否存在而返回true或者是false.关系表达式总是返回一个布尔值. 具有如下8个关系运算符:大于(>),小于(<),小于等于(<=), ...
- Vagrant box 增加磁盘容量方法
一直以来都是以vagrant+docker作为开发环境,可是久而久之,原Box自带的8G容量就捉襟见肘了.时不时需要手动删除一些东西. Virtualbox 本身只支持vdi硬盘文件格式的扩容,对vm ...
- PXE help Tips
http://www.kano.org.uk/projects/pxe/ http://howto.basjes.nl/linux/installing-fedora-linux-via-pxe-x8 ...
- Oracle笔记(五) 单行函数
虽然各个数据库都是支持SQL语句的,但是每一个数据库也有每一个数据库自己所支持的操作函数,这些就是单行函数,而如果要想进行数据库开发的话,除了要会使用SQL之外 ,就是要多学习函数. 单行函数主要分为 ...
- 【2017-03-28】JS基础、windows对象、history对象、location对象
一.JS基础 JS - javaScript 1.js功能: 1).进行数据的运算.2).控制浏览器的一些功能.3).控制元素(属性.内容.样式) js引用位置: 可以放在html页的任意位置. 推荐 ...
- BLE 5协议栈-属性协议层(ATT)
文章转载自:http://www.sunyouqun.com/2017/04/page/2/ 属性协议(Attribute Protocol)简称ATT. ATT层定义了属性实体的概念,包括UUID. ...
- IPC之mqueue.c源码解读
队列的意思应该大家都清楚,不过还有有一些细节的地方不知道,下面是一个队列的源码,因该说这是队列的一部分,不是全部.而且是linux中队列,其他各种OS中队列大同小异. /* * POSIX messa ...
- Activity的跳转及返回值 的四种方法
Activity生命周期 从创建到销毁的生命周期: onCreate()→onStart()→onResume()→onPouse()→onStop()→onDestroy() 从起动到后台再到前台: ...