CUDA stream利用CUDA流重叠计

本文涉及的产品
数据传输服务 DTS,同步至DuckDB 3个月
简介: CUDA stream利用CUDA流重叠计

利用CUDA流重叠计算和数据传输

CUDA中有一个重要的概念是 流(stream). 其实它代表着一系列的指令的执行队列. 这个执行队列就像他的名字一样, 有着固定的执行顺序(就像河流只能向一个方向固定的河道流淌一样).

而这条河的源头就是主机线程(host), 它开启了这个执行队列. 同样的, 也可能这座高山开启了不同的河流, 我们的主机线程(host)也可能启动了不同的执行队列. 或者多个主机线程(多座高山), 开启了多个stream(河流).

我更愿意理解流是更高一个层次的并行手段, 相对于thread, block 和 grid, 它的层级更高, 也更独立.

thread, block 和 grid其实都可以算作 kernel内的并行层次, 而流(stream)是kernel外的并行层次.

流(stream)分为默认流(或者叫做NULL流)非默认流.

默认流指的是你不显示声明,创建或指定的操作队列. 在任何CUDA程序中只要是你调用了kernel或调用相关的CUDA函数, 并且没指定他们运行在哪个流中, 那么他们会自动的被安排在默认流中.

或者你可以这么想, 当你开始CUDA程序的时候, 你调用的那些方法或函数就已经在默认流中了. 当你创建了新的流并把那些函数方法放在新的流中的时候, 他们才从默认流中解脱, 有了自己新的执行队列.

而你创建的那些新的流, stream0, stream1, stream2…就是非默认流.

CUDA流最重要的功能就是并发执行

这里提到的并发执行简单点说就是, 将要计算的数据或要处理的资源分割成多个部分, 让每个流分别处理.

这个流的概念也是其他基于CUDA的加速库使用最多的CUDA内容. 比如cuBLAS, cuFFT, TensorRT, cuDNN中的句柄概念就可以和CUDA流结合使用, 并发处理.

接下来我们分析一下这段代码:

for (int i = 0; i < 2; ++i)
    cudaMemcpyAsync(inputDevPtr + i * size, hostPtr + i * size,
                    size, cudaMemcpyHostToDevice, stream[i]);
for (int i = 0; i < 2; ++i)
    MyKernel<<<100, 512, 0, stream[i]>>>
          (outputDevPtr + i * size, inputDevPtr + i * size, size);
for (int i = 0; i < 2; ++i)
    cudaMemcpyAsync(hostPtr + i * size, outputDevPtr + i * size,
                    size, cudaMemcpyDeviceToHost, stream[i]);

在这段代码中:

  • 第一个for循环将数据从CPU内存传输给GPU显存中. 而传输的过程是将input分割成两部分. 分别放在stream[i]中进行传输.
  • 在第二个for循环中, MyKernel<<<100, 512, 0, stream[i]>>>分别在stream[i]中执行.
  • 第三个for循环分别在两个stream中讲计算完成的结果传输给CPU内存.

这里需要注意的是:

  • 这里传输的函数使用的是cudaMemcpyAsync, 它是一个异步传输的函数. 简单点说, 可以同时进行多个传输任务, 他们之间并不是一起执行的.
  • 我们在使用上述代码的时候, 需要手动的进行同步.

我们需要让程序知道这些流(执行队列)是否已经完成, 而显式的同步流的方法有以下几种:

  • cudaDeviceSynchronize() 一直等待,直到所有主机线程的所有流中的所有先前命令都完成。
  • cudaStreamSynchronize() 将流作为参数并等待,直到给定流中的所有先前命令都已完成。 它可用于将主机与特定流同步,允许其他流继续在设备上执行。
  • cudaStreamWaitEvent() 将流和事件作为参数(有关事件的描述,请参阅事件),并在调用 cudaStreamWaitEvent() 后使添加到给定流的所有命令延迟执行,直到给定事件完成。
  • cudaStreamQuery() 为应用程序提供了一种方法来了解流中所有前面的命令是否已完成。

重叠计算

理解了上面的内容, 我们就可以简单的理解了重叠计算的内容.

如上图所示, 我们同时进行数据传输和数据计算. 那么我们就将数据传输的时间隐藏在数据计算的过程中, 或者将数计算的时间隐藏在数据传输的过程中.

如果主机线程在它们之间发出以下任一操作,则来自不同流的两个命令不能同时运行:

  • 页面锁定的主机内存分配,
  • 设备内存分配,
  • 设备内存设置,
  • 两个地址之间的内存拷贝到同一设备内存,
  • 对 NULL 流的任何 CUDA 命令,
  • 计算能力 3.x 和计算能力 7.x 中描述的 L1/共享内存配置之间的切换。

对于支持并发内核执行且计算能力为 3.0 或更低的设备,任何需要依赖项检查以查看流内核启动是否完成的操作:

  • 仅当从 CUDA 上下文中的任何流启动的所有先前内核的所有线程块都已开始执行时,才能开始执行;
  • 阻止所有以后从 CUDA 上下文中的任何流启动内核,直到检查内核启动完成。

需要依赖检查的操作包括与正在检查的启动相同的流中的任何其他命令以及对该流的任何 cudaStreamQuery() 调用。 因此,应用程序应遵循以下准则来提高并发内核执行的潜力:

  • 所有独立操作都应该在依赖操作之前发出,
  • 任何类型的同步都应该尽可能地延迟。
相关实践学习
自建数据库迁移到云数据库
本场景将引导您将网站的自建数据库平滑迁移至云数据库RDS。通过使用RDS,您可以获得稳定、可靠和安全的企业级数据库服务,可以更加专注于发展核心业务,无需过多担心数据库的管理和维护。
Sqoop 企业级大数据迁移方案实战
Sqoop是一个用于在Hadoop和关系数据库服务器之间传输数据的工具。它用于从关系数据库(如MySQL,Oracle)导入数据到Hadoop HDFS,并从Hadoop文件系统导出到关系数据库。 本课程主要讲解了Sqoop的设计思想及原理、部署安装及配置、详细具体的使用方法技巧与实操案例、企业级任务管理等。结合日常工作实践,培养解决实际问题的能力。本课程由黑马程序员提供。
目录
相关文章
|
并行计算 异构计算
CUDA streamCUDA流的基本概念
CUDA streamCUDA流的基本概念
3303 0
CUDA streamCUDA流的基本概念
|
存储 编解码 对象存储
Python提取指定时间、经度与纬度的NC数据
【2月更文挑战第15天】本文介绍基于Python语言的netCDF4库,读取.nc格式的数据文件,并提取指定维(时间、经度与纬度)下的变量数据的方法~
960 3
Python提取指定时间、经度与纬度的NC数据
|
8月前
|
负载均衡 测试技术 调度
大模型分布式推理:张量并行与流水线并行技术
本文深入探讨大语言模型分布式推理的核心技术——张量并行与流水线并行。通过分析单GPU内存限制下的模型部署挑战,详细解析张量并行的矩阵分片策略、流水线并行的阶段划分机制,以及二者的混合并行架构。文章包含完整的分布式推理框架实现、通信优化策略和性能调优指南,为千亿参数大模型的分布式部署提供全面解决方案。
2328 4
|
资源调度
一天掌握latex论文编辑,从标题作者,段落,数学公式,图片,图表,到参考文献全流程
一天掌握latex论文编辑,从标题作者,段落,数学公式,图片,图表,到参考文献全流程
2136 0
|
数据可视化 Serverless 数据处理
【优秀python案例】基于python因子分析关于城市发展差异分析中的应用与实现
本文利用Python进行因子分析,揭示了影响中国东西部地区发展差异的关键因素,为促进区域均衡发展和协调增长提供了科学依据。
688 107
【优秀python案例】基于python因子分析关于城市发展差异分析中的应用与实现
|
存储 机器学习/深度学习 并行计算
【AI系统】Tensor Core 深度剖析
Tensor Core 是英伟达 GPU 的关键技术,专为加速深度学习计算设计,尤其擅长矩阵乘法和卷积运算。通过混合精度计算,Tensor Core 使用半精度(FP16)输入输出,内部以全精度(FP32)计算,确保精度同时提高效率。相比传统 CUDA Core,Tensor Core 每个时钟周期可执行 64 个浮点运算,大幅提升计算速度。其工作原理包括指令流水线、线程执行等多级优化,确保高效并行处理。通过分块、分配和并行执行策略,Tensor Core 能有效处理大规模矩阵计算,极大加速神经网络模型的训练和推断。
1539 1
【AI系统】Tensor Core 深度剖析
|
Linux 开发工具 Android开发
[√]leak tracer的stack address始终无法被addr2line识别
[√]leak tracer的stack address始终无法被addr2line识别
476 0
|
人工智能 弹性计算 并行计算
技术改变AI发展:CUDA Graph优化的底层原理分析(GPU底层技术系列一)
随着人工智能(AI)的迅速发展,越来越多的应用需要巨大的GPU计算资源。CUDA是一种并行计算平台和编程模型,由Nvidia推出,可利用GPU的强大处理能力进行加速计算。
108446 1
|
JavaScript 前端开发 算法
前端优化之超大数组更新:深入分析Vue/React/Svelte的更新渲染策略
本文对比了 Vue、React 和 Svelte 在数组渲染方面的实现方式和优缺点,探讨了它们与直接操作 DOM 的差异及 Web Components 的实现方式。Vue 通过响应式系统自动管理数据变化,React 利用虚拟 DOM 和 `diffing` 算法优化更新,Svelte 通过编译时优化提升性能。文章还介绍了数组更新的优化策略,如使用 `key`、分片渲染、虚拟滚动等,帮助开发者在处理大型数组时提升性能。总结指出,选择合适的框架应根据项目复杂度和性能需求来决定。
840 2
|
机器学习/深度学习 监控 搜索推荐
深度粗排模型的GMV优化实践:基于全空间-子空间联合建模的蒸馏校准模型
随着业务的不断发展,粗排模型在整个系统链路中变得越来越重要,能够显著提升线上效果。本文是对粗排模型优化的阶段性总结。
2355 0
深度粗排模型的GMV优化实践:基于全空间-子空间联合建模的蒸馏校准模型