• 本站由于前段时间遭受到大量临时和国外邮箱注册,所以对可注册的邮箱类型进行了限制!

  • 感谢大家访问本站,希望本站的内容可以帮助到大家!

  • 如果觉得本站的内容有帮助,可以考虑打赏博主哦!

  • 工资「喂饱肚子」,副业「养活灵魂」!

  • 问题反馈可发送邮件到stubbornhuang@qq.com

  • 欢迎大家交换友链,可在https://www.stubbornhuang.com/申请友情链接进行友链交换申请!

  • 本站会放置Google广告用于维持域名以及网站服务器费用。

  • 计算机图形学与计算几何经典必备书单整理,下载链接可参考:https://www.stubbornhuang.com/1256/

  • 在本站开通年度VIP,无限制下载本站资源和阅读本站文章

GPU并发?理解CUDA的并发执行与计算资源调度

NVIDIA 发布于2024-01-19 阅读 2,315次 0次评论 1次点赞 本文共2046个字,阅读需要6分钟。

## 1 CUDA计算是否可以并发?

CUDA程序运行中CPU端一般叫做host,GPU端一般叫做Device。

  1. CPU端对计算资源进行划分的单位为进程,GPU端对计算资源进行划分的单位为context。多核心CPU可以同一时刻多个进程/线程并发执行,GPU一个时刻只允许一个context允许,也就是说GPU端一个时刻只允许被CPU端的一个进程所调用执行(没开启mps的情况下)。
  2. 一个CPU端的一个调用CUDA的进程在GPU上可以有一个或多个context。如果CPU端某个进程调用的cuda代码是runtime api级别的,那么在GPU上该进程对应的context只有一个;如果CPU端进程调用的cuda代码是driver api级别的,那么在GPU上该进程对应的context可以有多个。但是需要注意不论CPU端进行调用的进程所对应的GPU端的context有一个还是多个,GPU上一个时刻只能运行一个context。
  3. 由于GPU在一个时刻只能运行一个context,但是往往一个context的运行并不能使整个GPU计算资源得到利用,所以nvidia推出了mps服务。mps服务可以把同一个用户名下的多个CPU进程所对应的GPU端的多个context融合成一个context,这样一个GPU在开启mps服务后虽然依然是一个时刻只能运行一个context,但是此时的context是多个CPU端进程所对应的多个context融合成的,那么此时一个时刻下就可以运行多个之前的同用户的多个进程所对应的context,这样就能同时刻多个kernel运行,提高GPU的利用效率。
  4. CPU端同一进程下的多个线程同时刻并发调用GPU端的同一个context,此时GPU端在同一个context下是否能同时刻运行多个cuda调用就需要看此时的多个cuda调用是否在同一个steam队列中。一般情况下cuda代码中都是默认使用一个stream队列,因此即使CPU端多线程同时调用cuda最终也只能对请求进行排队运行。如果cuda代码中明确把多线程的调用操作写为不同stream队列,那么便可实现GPU端同时刻下多个kernel的运行。
  5. CPU端一个进程(单进程单线程)内对多个kernel进行异步调用,并且这些kernel的操作都是写在了不同的stream队列中,并且这个cuda代码(.cu文件)使用 --default-stream per-thread 参数进行nvcc的编译。

在GPU端默认一个时刻下只能运行一个kernel,但以下三种情况可以有多个kernel

  1. 开启了mps服务后同用户的多个进程调用可以同时刻在GPU上运行,实现kernel的并发执行;
  2. 一个进程的多个线程调用写明不同stream队列的kernel操作,并且代码使用 --default-stream per-thread 参数进行nvcc的编译。
  3. 一个进程(单线程)异步调用写明不同stream队列的kernel操作,并且代码使用 --default-stream per-thread 参数进行nvcc的编译。

不过这三种方式都有极大的缺点,开启mps服务后显卡只能被单个用户所独占,只有该用户的所有cuda任务结束释放掉所有GPU资源后才可以给其他用户调用该显卡的cuda;将cuda操作写为多个stream队列往往需要额外的编码开销,该种方式比较适合小规模的开发任务,对于一些大型的cuda计算框架难以实现,比如TensorFlow、pytorch等基本都没有实现cuda调用的多stream操作。因为CPU端多进程/多线程调用CUDA并发的一些限制(写明不同的stream队列以及编译时的参数指定等),现在几乎所有的CUDA应用都是单进程单线程调用cuda并且kernel排队运行,也就是说绝大部分的cuda应用都是同一个时刻只有一个cpu线程可以调用GPU端的CUDA(一个时刻只有一个kernel在运行),而一个GPU端的多个CPU进程的调用都是通过分时系统进行的。

不管GPU端是否可以多kernel并发,HOST和Device间的数据传输在一个时刻下都只能是单个操作,也就是说一个时刻下host端向device的数据传输只能是一个cuda调用,但是在host向device传输数据的同时device可以向host同时传输数据,同理同一时刻下device向host传输数据也只能是以cuda操作,不论GPU端的cuda操作是否有多个stream队列,单向的数据传输都是不能并发的。

CPU端同时刻可以运行同进程的多个线程,GPU端同时刻只能运行一个context。在mps没有开启的情况下,如果GPU端一个context内的多个kernel操作写在不同stream队列中并且加入特定编译参数才可以实现GPU端的多kernel并发。

参考

欢迎扫码关注我的微信公众号,及时获取文章更新

微信公众号二维码

本文作者:StubbornHuang

版权声明:本文为站长原创文章,如果转载请注明原文链接!

原文标题:GPU并发?理解CUDA的并发执行与计算资源调度

原文链接:https://www.stubbornhuang.com/2962/

发布于:2024年01月19日 14:30:23

修改于:2024年01月19日 14:30:23

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

文章末尾
上一篇
资源分享 - C++ Templates, Second Edition 英文PDF下载
C++资源
下一篇
资源分享 - Code Complete, Second Edition 英文PDF下载
C++资源
当前分类随机文章推荐

发表评论

您必须 [ 登录 ] 才能发表留言!

关注我们的公众号

微信公众号