欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 时评 > 【知识】CUDA Stream和并发性

【知识】CUDA Stream和并发性

2025/9/25 18:21:04 来源:https://blog.csdn.net/sxf1061700625/article/details/143492261  浏览:    关键词:【知识】CUDA Stream和并发性

转载请注明出处:小锋学长生活大爆炸[xfxuezhagn.cn]

如果本文帮助到了你,欢迎[点赞、收藏、关注]哦~

翻译来自:

Streams And Concurrency Webinar

可以看原版pdf,本博客只是挑选并翻译一下。


支持同时执行多个CUDA操作的能力 (超越了多线程并行性)

  • CUDA Kernel <<<>>>
  • cudaMemcpyAsync (HostToDevice)
  • cudaMemcpyAsync (DeviceToHost)
  • CPU上的操作

Fermi架构可以同时支持 (要求计算能力2.0+)

  • 在GPU上最多有16个CUDA Kernel
  • 2个cudaMemcpyAsyncs(必须是在不同的方向上)
  • CPU上的计算

Stream:在GPU上按问题顺序执行的一系列操作。用于影响并发性的编程模型:

  • 不同流中的CUDA操作可以并发地进行
  • 来自不同流的CUDA操作可以交错进行

默认Stream (又称为 Stream 0),即未指定流时使用的流。

并发性要求

  • CUDA操作必须在不同的、非0的流中;
  • cudaMemcpyAsync时是主机中的'pinned' memory;
  • 必须有足够的资源:
    • cudaMemcpyAsyncs在不同的方向上;
    • 设备资源(SMEM、registers、blocks等);

简单的同步示例:默认流中的所有CUDA操作都是同步的

简单的异步且没有流的示例:默认情况下,GPU内核与主机是异步的

简单的使用了流的异步示例:完全异步/并发,并发操作所使用的数据需要是独立的

显式同步的情况

  • 同步所有内容
    • cudaDeviceSynchronize ()
    • 阻止主机,直到所有发出的CUDA调用都完成
  • 特定的流中同步w.r.t.
    • cudaStreamSynchronize ( streamid )
    • 阻塞主机,直到流中的所有CUDA调用完成
  • 使用事件同步
    • 在流中创建特定的“事件”,以用于同步
    • cudaEventRecord ( event, streamid )
    • cudaEventSynchronize ( event )
    • cudaStreamWaitEvent ( stream, event )
    • cudaEventQuery ( event )

显式同步示例:使用事件解决

隐式同步:这些操作会隐式地同步所有其他CUDA操作

  • 锁定页面的内存分配
    • cudaMallocHost
    • cudaHostAlloc
  • 设备内存分配
    • cudaMalloc
  • 内存操作的非异步版本
    • cudaMemcpy* (no Async suffix)
    • cudaMemset* (no Async suffix)
  • 更改为L1/共享内存配置
    • cudaDeviceSetCacheConfig

流的调度

  • Fermi硬件有3个队列
    • 1个计算引擎队列
    • 2个复制引擎队列:一个用于H2D,一个用于D2H
  • CUDA操作按它们被发布的顺序被发送到HW
    • 被放置在相关的队列中
    • 维护了引擎队列之间的流依赖关系,但在引擎队列中丢失
  • 如果出现以下情况,则将从引擎队列分派CUDA操作:
    • 在同一流中的先前的调用已经完成
    • 在同一流中的先前的调用已经分派
    • 资源可用
  • 如果CUDA内核在不同的流中,则可以并发地执行它们
    • 如果前面内核的所有线程块都已调度,并且仍然有SM资源可用,则调度给定内核的线程块
  • 请注意,一个被阻塞的操作会阻止队列中的所有其他操作,甚至在其他流中

Blocked Queue的示例

最优并发性可能取决于内核的执行时间

并发内核的调度

  • 并发内核调度很特殊
  • 通常,在操作后将信号插入队列,在同一流中启动下一个操作
  • 对于计算引擎队列,若要启用并发内核,当计算内核按顺序发出时,该信号将延迟到最后一个顺序计算内核之后
  • 在某些情况下,这种信号的延迟可能会阻塞其他队列

并发内核和阻塞的示例

其他的详细信息

  • 很难同时运行超过4个内核
  • 可以使用环境变量禁用并发性:CUDA_LAUNCH_BLOCKING
  • cudaStreamQuery可以用来分离连续的核,防止延迟信号
  • 使用超过8个textures的内核不能并发运行
  • 切换L1/共享配置将破坏并发性
  • 要并发运行,CUDA操作必须有不超过62个介入的CUDA操作。也就是说,按照“问题顺序”,它们不能被超过62个其他问题分开,进一步的操作会被序列化。
  • cudaEvent_t对于计时很有用,但对于性能的使用可以用cudaEventCreateWithFlags ( &event, cudaEventDisableTiming )

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词