news 2026/9/3 2:41:57

CUDA高性能计算系列06:流 (Stream) 与并发执行

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
CUDA高性能计算系列06:流 (Stream) 与并发执行

CUDA高性能计算系列06:流 (Stream) 与并发执行

摘要:在之前的文章中,我们的视角主要集中在 GPU 内部(Kernel 优化)。但在宏观层面,CPU 和 GPU 是两个独立的处理器,GPU 内部也有拷贝引擎(Copy Engine)和计算引擎(Compute Engine)。本篇将引入CUDA Stream (流)的概念,教你如何像“流水线工厂”一样编排任务,实现数据传输与计算的完美重叠 (Overlap),从而隐藏掉昂贵的 PCIe 传输延迟。


1. 默认的同步行为:串行执行

在没有显式使用 Stream 的情况下,所有的 CUDA 命令(Kernel 启动,cudaMemcpy)都会被提交给一个默认流 (Default Stream)。默认流保证了命令的顺序执行

让我们回顾一下典型的深度学习训练循环:

for(inti=0;i<n_batches;++i){cudaMemcpy(d_in,h_in,size,H2D);// Copy H2D (Host to Device)myKernel<<<grid,block>>>(d_in,d_out);// Kernel ComputecudaMemcpy(h_out,d_out,size,D2H);// Copy D2H (Device to Host)}

时间线视图 (Timeline)

00010203040506070809101112Copy H2DKernelCopy D2HCopy H2D (Batch 2)Kernel (Batch 2)Default Stream默认流串行执行 (无重叠)

问题

  • 当 GPU 在计算 Kernel 时,PCIe 总线是闲置的。
  • 当数据在 PCIe 上传输时,GPU 核心是闲置的。
  • 资源利用率低下

2. CUDA Stream:异步并发的钥匙

CUDA Stream是一个 GPU 操作队列。

  • 流内顺序:同一个流中的操作严格按顺序执行。
  • 流间乱序:不同流中的操作可以并发执行(只要硬件资源允许)。

2.1 硬件引擎支持

现代 NVIDIA GPU 拥有独立的引擎:

  1. Compute Engine:负责执行 Kernel。
  2. Copy Engine (H2D):负责 Host 到 Device 传输。
  3. Copy Engine (D2H):负责 Device 到 Host 传输。

这意味着,理论上我们可以同时做这三件事:向 GPU 拷入数据、GPU 计算、从 GPU 拷出数据。


3. 异步编程实战

要实现重叠,我们需要做两件事:

  1. 创建多个 Stream。
  2. 使用异步 API

3.1 关键 API

// 1. 创建流cudaStream_t stream[n_streams];for(inti=0;i<n_streams;++i)cudaStreamCreate(&stream[i]);// 2. 异步内存拷贝 (必须使用 Pinned Memory!)// 注意:最后一个参数传入 stream[i]cudaMemcpyAsync(d_dst,h_src,size,kind,stream[i]);// 3. 异步 Kernel 启动// 第 4 个参数传入 stream[i] (第 3 个参数是 shared memory size,通常为 0)myKernel<<<grid,block,0,stream[i]>>>(...);// 4. 同步流 (等待流内所有操作完成)cudaStreamSynchronize(stream[i]);// 5. 销毁流cudaStreamDestroy(stream[i]);

3.2 锁页内存 (Pinned Memory)

非常重要:要使用cudaMemcpyAsync实现真正的异步传输,Host 端的内存必须是Pinned Memory (锁页内存),不能是操作系统默认的分页内存。

// 申请float*h_ptr;cudaMallocHost((void**)&h_ptr,size);// 代替 malloc// 释放cudaFreeHost(h_ptr);// 代替 free

3.3 流水线设计 (Pipelining)

我们将大任务切分成NNN个小块(Chunks),分别放入NNN个 Stream 中处理。

深度优先 (Depth-First) 调度(推荐):
Loop over streams:

  1. Async Copy H2D (Streamiii)
  2. Async Kernel (Streamiii)
  3. Async Copy D2H (Streamiii)

时间线视图 (Pipeline)

000102030405060708091011Stream 1Stream 2Stream 1Stream 3Stream 2Stream 1Stream 3Stream 2Stream 3Copy Engine (H2D)Compute EngineCopy Engine (D2H)多流并行 (3路流水线)

可以看到,Stream 2 的 Copy H2DStream 1 的 Kernel重叠了;Stream 3 的 Copy H2DStream 2 的 KernelStream 1 的 Copy D2H甚至可以三者重叠!


4. 完整代码示例

#include<stdio.h>#include<cuda_runtime.h>#defineN30000000// 总数据量#defineN_STREAMS4// 流的数量constintSTREAM_SIZE=N/N_STREAMS;constintSTREAM_BYTES=STREAM_SIZE*sizeof(float);__global__voidsimpleKernel(float*a,float*b,float*c,intoffset){inti=offset+blockIdx.x*blockDim.x+threadIdx.x;if(i<N){// 增加计算负载,让 Kernel 耗时比 Copy 长,更容易观察到重叠for(intk=0;k<100;k++)c[i]=sinf(a[i])+cosf(b[i]);}}intmain(){float*h_a,*h_b,*h_c;float*d_a,*d_b,*d_c;// 1. 分配 Pinned Host MemorycudaMallocHost((void**)&h_a,N*sizeof(float));cudaMallocHost((void**)&h_b,N*sizeof(float));cudaMallocHost((void**)&h_c,N*sizeof(float));// 初始化数据...for(inti=0;i<N;i++){h_a[i]=i;h_b[i]=i;}// 2. 分配 Device MemorycudaMalloc((void**)&d_a,N*sizeof(float));cudaMalloc((void**)&d_b,N*sizeof(float));cudaMalloc((void**)&d_c,N*sizeof(float));// 3. 创建 StreamcudaStream_t stream[N_STREAMS];for(inti=0;i<N_STREAMS;++i)cudaStreamCreate(&stream[i]);// 4. 流水线循环for(inti=0;i<N_STREAMS;++i){intoffset=i*STREAM_SIZE;// Async Copy H2DcudaMemcpyAsync(&d_a[offset],&h_a[offset],STREAM_BYTES,cudaMemcpyHostToDevice,stream[i]);cudaMemcpyAsync(&d_b[offset],&h_b[offset],STREAM_BYTES,cudaMemcpyHostToDevice,stream[i]);// Async KernelsimpleKernel<<<STREAM_SIZE/256,256,0,stream[i]>>>(d_a,d_b,d_c,offset);// Async Copy D2HcudaMemcpyAsync(&h_c[offset],&d_c[offset],STREAM_BYTES,cudaMemcpyDeviceToHost,stream[i]);}// 5. 同步所有流 (等待所有任务完成)cudaDeviceSynchronize();// 6. 清理资源for(inti=0;i<N_STREAMS;++i)cudaStreamDestroy(stream[i]);cudaFreeHost(h_a);cudaFreeHost(h_b);cudaFreeHost(h_c);cudaFree(d_a);cudaFree(d_b);cudaFree(d_c);return0;}

5. 性能验证:Nsight Systems

要真正确认“重叠”发生了,最好的工具是Nsight Systems (nsys)。它能生成可视化的时间线。

运行命令:

nsys profile -o my_timeline ./my_stream_app

然后用 GUI 打开my_timeline.qdrep

预期效果
你会看到 Copy 栏和 Compute 栏在时间轴上是垂直对齐的(重叠),而不是阶梯状分布。如果 Copy H2D 比较快,Kernel 比较慢,你应该能看到 Kernel 紧密地排在一起,几乎没有空隙。


6. 总结与下篇预告

通过 CUDA Stream,我们打破了“传数据 -> 算数据 -> 传回数据”的串行枷锁,实现了Host 与 DeviceCopy 与 Compute的全面并发。这对于处理视频流、实时推理等延迟敏感型任务至关重要。

现在,我们已经榨干了内存带宽(第3-5篇)和流水线并发(第6篇)。但是,我们的 Kernel 代码内部还在用着最基础的if-else吗?你知道if语句在 GPU 上可能导致巨大的性能陷阱吗?

下一篇[CUDA系列07_Warp Divergence与指令优化](./CUDA系列07_Warp Divergence与指令优化.md),我们将深入微观指令层面,探讨Warp Divergence (线程束分化)现象,并学习如何写出对 SIMT 架构友好的分支代码。


参考文献

  1. NVIDIA Corporation.CUDA C++ Programming Guide - Asynchronous Concurrent Execution. 2024.
  2. Khronos Group.Vulkan & CUDA Interop / Concurrency.
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/26 20:38:00

零基础掌握AUTOSAR诊断协议栈(UDS over CAN)

零基础吃透AUTOSAR诊断协议栈&#xff1a;从UDS到CAN&#xff0c;拆解整车刷写与故障读取的底层逻辑 你有没有遇到过这样的场景&#xff1f; 产线上的ECU突然无法刷写&#xff0c;诊断仪反复提示“安全访问拒绝”&#xff1b; 售后反馈某车型OBD灯常亮&#xff0c;但用标准工…

作者头像 李华
网站建设 2026/9/2 1:16:30

实战案例:基于车载雷达模块的CANFD与CAN对比

实战案例&#xff1a;车载毫米波雷达通信&#xff0c;为什么CANFD正在取代传统CAN&#xff1f;在一辆智能汽车的“神经系统”中&#xff0c;传感器是感知世界的“眼睛”和“耳朵”&#xff0c;而通信总线就是传递信息的“神经纤维”。当77GHz毫米波雷达每秒输出数百个目标点时&…

作者头像 李华
网站建设 2026/9/2 23:34:30

CUDA 11.0 共享库缺失:环境配置实战案例解析

CUDA 11.0 共享库缺失实战排错&#xff1a;从 ImportError 到 GPU 可用的完整路径 你有没有在深夜调试模型时&#xff0c;刚运行 import torch 就被一条红色报错拦住去路&#xff1f; ImportError: libcudart.so.11.0: cannot open shared object file: No such file or…

作者头像 李华
网站建设 2026/9/2 23:41:33

基于SSM框架的房屋中介公司网站

基于SSM框架的房屋中介公司网站介绍 一、技术架构与核心优势 基于SSM&#xff08;SpringSpringMVCMyBatis&#xff09;框架开发的房屋中介网站&#xff0c;采用经典的MVC分层设计模式&#xff0c;具备以下技术优势&#xff1a; 高扩展性 Spring的IoC容器实现模块解耦&#xff0…

作者头像 李华
网站建设 2026/9/3 2:10:53

智能驾驶域中CANFD带宽优化的项目应用

智能驾驶域中CAN FD带宽优化的实战经验&#xff1a;从92%负载到68%的破局之路在当前智能驾驶系统快速迭代的背景下&#xff0c;通信瓶颈正悄然成为制约性能提升的关键“隐性天花板”。我们曾在一个量产级L2智能驾驶项目中遭遇这样的挑战&#xff1a;域控制器集成多路雷达、摄像…

作者头像 李华
网站建设 2026/8/27 6:43:12

AI大模型是程序员必备技能吗?该如何学习储备?

AI大模型是程序员必备技能吗&#xff1f;该如何学习储备&#xff1f; AI大模型正迅速成为程序员的重要工具&#xff0c;但“必备技能”需结合具体领域辩证看待。以下为结构化分析及学习路径&#xff1a; 一、AI大模型的必要性分析 效率工具 代码生成&#xff08;如GitHub Copi…

作者头像 李华