DAY11:阅读CUDA异步并发执行中的Event和同步调用

今天内容比较简单,讲解Events和同步调用。自此,关于异步并发执行部分的1.主机与GPU之间的并发执行;2.内核并发执行;3.数据传输和内核执行之间的重叠;4.并行数据传输;5.Stream;6.Event;7.同步调用 就全部讲完。

3.2.5.6. Events【事件】

The runtime also provides a way to closely monitor the device's progress, as well as perform accurate timing, by letting the application asynchronously record events at any point in the program and query when these events are completed. An event has completed when all tasks - or optionally, all commands in a given stream - preceding the event have completed. Events in stream zero are completed after all preceding tasks and commands in all streams are completed.

3.2.5.6.1. Creation and Destruction

The following code sample creates two events:

They are destroyed this way:

3.2.5.6.2. Elapsed Time

The events created in Creation and Destruction can be used to time the code sample of Creation and Destruction the following way:

3.2.5.7. Synchronous Calls【同步调用】

When a synchronous function is called, control is not returned to the host thread before the device has completed the requested task. Whether the host thread will then yield, block, or spin can be specified by calling cudaSetDeviceFlags()with some specific flags (see reference manual for details) before any other CUDA call is performed by the host thread.

本文备注/经验分享:

Events就是事件,而事件是用来同步和时间测量的一种机制,请注意英文教材中的同步往往和中文教材的同步意思不同,英文(例如国外教材)中的同步往往叫查询操作也叫同步。所以精确的说,事件是用来同步,查询完成状态,以及测量时间的一种机制。CUDA允许使用不带用测时功能的事件。如果选择了不带测时功能,则只有前面两种功能了(阻塞式的等待同步,和轮询式的非阻塞同步,或者用户也可以选择这两种的综合---例如先轮询一段时间,然后再阻塞等待,请注意用户选择的阻塞式等待是从用户的角度来看的。Runtime/Driver可以继续将用户的逻辑角度的阻塞等待继续实现成轮询,或者直接阻塞,或者轮询一段时间后再阻塞。)。

They are destroyed this way:event没有停止的概念,只有发生了(实际的被recorded了)和没有发生。你看到的函数是销毁这两个event,往往在程序结束的时候出现(类似的,也有cudaFree()等伴随出现。后者是释放显存)。只有event发生了,和没有发生。没有开始和停止的说法的,发生了可以带着一个时刻,请注意是时刻(例如3点5分),而不是时间长短,正因为是时刻,你需要2个events,将他们发生的时刻相减,才能得到时间。所以你看到的测时代码都用来2个events,而不是1个。record event 1, 启动kernel, record event 2,你知道流是顺序执行的。那么当event 2发生后,kernel已经执行完了,event 1也发生了,而此时,你得到了2个时刻(event 2和event 1的发生时刻),两个相减,就是中间的kernel的执行时间。你可能会怀疑,event本身被record的过程,不需要时间么?这个非常非常快,可以忽略。

Elapsed Time流逝的时间,就是刚才说过的,流中:event 1,kernel(或者多个kernel等),event 2,然后只要等待event 2完成了,然后用event 2的时刻,再和event 1的时刻做减,就能得到中间的kernel(或者多个kernel等操作)的用时了。

Synchronous Calls这就是常规的调用(同步调用,阻塞调用),很多无Async结尾的CUDA函数,都是同步调用的。(在CUDA函数完成前不返回控制权给host thread,host thread将被block住。)

Whether the host thread will then yield, block, or spin can be specified by calling cudaSetDeviceFlags()with some specific flags (see reference manual for details) before any other CUDA call is performed by the host thread. 当从host程序的逻辑角度看,某阻塞式函数(例如cudaMalloc, 例如cudaMemcpy)将导致host线程暂停运行,也就是看上去阻塞在这些普通函数上了,不过内地里,究竟Runtime或者Driver是将在那里真的阻塞,还是在那里反复轮训自旋,还是yield放弃时间片,是内部实现的问题。你可以强制通过cudaSetDeviceFlags()来要求一种。小提示:如果不是启动非常非常小的kernel,建议总是选择阻塞。非常非常小的kernel,非常短时间就能返回的,建议选择spin,或者yield。我的习惯是上去就选择BlockingSync要求阻塞。因为我从来不写非常非常小的kernel,执行时间在us级别的那种。轮询Spin适合非常小的kernel的,可以有更低的延迟,但为何我们几乎不需要选他?因为(1)几乎没有人写这么短暂就结束的小kernel,(2)往往我们调度都是一次性发布大量的命令给一个Queue中的,而很少有人一个小kernel结束就立刻需要host端判断结果,进行下一步的其他可能命令发布。根据实际来看,BlockingSync总是有更好的性能的,而不是手册的说法。上面的第二个,可以改成设备端的动态并行,这个比你在host上自旋轮询,延迟更低。不过动态并行需要计算能力3.5+的卡。总之建议用户总是设定BlockingSync的设备标志。

有不明白的地方,请在本文后留言

或者在我们的技术论坛bbs.gpuworld.cn上发帖

原文发布于微信公众号 - 吉浦迅科技(gpusolution)

原文发表时间:2018-05-14

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Java帮帮-微信公众号-技术文章全总结

Java并发学习1【面试+工作】

1798
来自专栏逸鹏说道

C#线程篇---让你知道什么是线程(1)

线程线程,进程进程,到底什么是线程,什么是熟练多线程编程? 今天来和大家一起讨论讨论线程基础,让大家知道线程的基本构造。 说线程之前,先要了解下进程,这个可不能...

3509
来自专栏Golang语言社区

信号量,锁和 golang 相关源码分析

本文为社区粉丝原创投稿,再次感谢作者南瓜waniu的分享,欢迎大家在评论区留言和作者讨论,同时也欢迎大家踊跃投稿,分享您的golang语言学习经验!投稿邮箱地址...

1463
来自专栏程序猿成长计划

RabbitMQ发布订阅实战-实现延时重试队列

RabbitMQ是一款使用Erlang开发的开源消息队列。本文假设读者对RabbitMQ是什么已经有了基本的了解,如果你还不知道它是什么以及可以用来做什么,建议...

6294
来自专栏逸鹏说道

【推荐】C#线程篇---你所不知道的线程池(4)

线程的创建和销毁都要耗费大量的时间,有什么更好的办法?用线程池! 太多的线程浪费内存资源,有什么更好的办法?用线程池! 太多线程有损性能,有什么更好的办法?用线...

3328
来自专栏王亚昌的专栏

【Zookeeper】Leader选举机制示例

一、 选项设置 提到Leader选举,先需要重点介绍下创建znode时的Flag选项。

580
来自专栏欧阳大哥的轮子

Windows窗口消息和消息队列

所有基于事件驱动的操作系统中的GUI程序,都会在主线程中运行一个消息泵来从消息队列中取出消息并执行对应的处理逻辑。消息队列中的消息除了由系统产生外,还提供了对应...

665
来自专栏大学生计算机视觉学习DeepLearning

c++ 网络编程(二)TCP/IP linux 下多进程socket通信 多个客户端与单个服务端交互代码实现回声服务器

原文链接:https://www.cnblogs.com/DOMLX/p/9612820.html

1018
来自专栏海纳周报

多线程内幕

本文是HinusWeekly第三期的第二篇文章,第三期的主题就是多线程编程。本文试图从单核CPU的角度讨论并发编程的困难。 函数调用的过程,就是不断地创建栈帧,...

3278
来自专栏xingoo, 一个梦想做发明家的程序员

完成端口IO模型

IOCP(IO完成端口)是一种伸缩性的IO模型,广泛应用于各种类型的高性能服务器,如Apache等。 IO完成端口,应用程序使用线程池处理异步IO请求的一种机制...

1918

扫码关注云+社区