CUDA Stream流并发性

2023-05-16

目录

1、CUDA 中的异步命令

2、默认流

3、Multistream多流示例


异构计算是指高效地使用系统中的所有处理器,包括 CPU 和 GPU 。为此,应用程序必须在多个处理器上并发执行函数。 CUDA 应用程序通过在 streams 中执行异步命令来管理并发性,这些命令是按顺序执行的。不同的流可以并发地执行它们的命令,也可以彼此无序地执行它们的命令。在不指定流的情况下执行异步 CUDA 命令时,运行时使用默认流。在 CUDA 7 之前,默认流是一个特殊流,它隐式地与设备上的所有其他流同步。CUDA7引入了大量强大的新功能,包括一个新的选项,可以为每个主机线程使用独立的默认流,这避免了传统默认流的序列化。本文将展示如何在 CUDA 程序中简化实现内核和数据副本之间的并发。

1、CUDA 中的异步命令

如 CUDA C 编程指南所述,异步命令在设备完成请求的任务之前将控制权返回给调用主机线程(它们是非阻塞的)。这些命令是:

  • 内核启动;
  • 存储器在两个地址之间复制到同一设备存储器;
  • 从主机到设备的 64kb 或更少内存块的内存拷贝;
  • 由后缀为 Async 的函数执行的内存复制;
  • 内存设置函数调用。

为内核启动或主机设备内存复制指定流是可选的;可以调用 CUDA 命令而不指定流(或通过将 stream 参数设置为零)。下面两行代码都在默认流上启动内核。

  kernel<<< blocks, threads, bytes >>>();    // default stream
  kernel<<< blocks, threads, bytes, 0 >>>(); // stream 0

2、默认流

在并发性对性能不重要的情况下,默认流很有用。在 CUDA 7 之前,每个设备都有一个用于所有主机线程的默认流,这会导致隐式同步。正如 CUDA C 编程指南中的“隐式同步”一节所述,如果主机线程向它们之间的默认流发出任何 CUDA 命令,来自不同流的两个命令就不能并发运行。CUDA 7 引入了一个新选项, 每线程默认流 ,它有两个效果。首先,它为每个主机线程提供自己的默认流。这意味着不同主机线程向默认流发出的命令可以并发运行。其次,这些默认流是常规流。这意味着默认流中的命令可以与非默认流中的命令同时运行。要在 nvcc 7 及更高版本中启用每线程默认流,可以在包含 CUDA 头( cuda.h 或 cuda_runtime.h )之前,使用 nvcc 命令行选项 CUDA 或 #define 编译 CUDA_API_PER_THREAD_DEFAULT_STREAM 预处理器宏。需要注意的是:当代码由 nvcc 编译时,不能使用 #define CUDA_API_PER_THREAD_DEFAULT_STREAM 在. cu 文件中启用此行为,因为 nvcc 在翻译单元的顶部隐式包含了 cuda_runtime.h 。

3、Multistream多流示例

看一个小例子。下面的代码简单地在八个流上启动一个简单内核的八个副本。只为每个网格启动一个线程块,这样就有足够的资源同时运行多个线程块。作为遗留默认流如何导致序列化的示例,在默认流上添加不起作用的虚拟内核启动

const int N = 1 << 20;
 
__global__ void kernel(float *x, int n)
{
    int tid = threadIdx.x + blockIdx.x * blockDim.x;
    for (int i = tid; i < n; i += blockDim.x * gridDim.x) {
        x[i] = sqrt(pow(3.14159,i));
    }
}
 
int main()
{
    const int num_streams = 8;
 
    cudaStream_t streams[num_streams];
    float *data[num_streams];
 
    for (int i = 0; i < num_streams; i++) {
        cudaStreamCreate(&streams[i]);
 
        cudaMalloc(&data[i], N * sizeof(float));
 
        // launch one worker kernel per stream
        kernel<<<1, 64, 0, streams[i]>>>(data[i], N);
 
        // launch a dummy kernel on the default stream
        kernel<<<1, 1>>>(0, 0);
    }
 
    cudaDeviceReset();
 
    return 0;
}

首先让检查遗留行为,通过不带选项的编译:


nvcc ./stream_test.cu -o stream_legacy  

可以在 NVIDIA visualprofiler ( nvvp )中运行该程序,以获得显示所有流和内核启动的时间轴。图 1 显示了 Macbook Pro 上生成的内核时间线,该 Macbook Pro 带有 NVIDIA GeForce GT 750M (一台开普勒 GPU )。可以看到默认流上虚拟内核的非常小的条,以及它们如何导致所有其他流序列化。

一个简单的多流示例在将任何交错内核发送到默认流时不会实现并发

现在尝试新的每线程默认流。


nvcc --default-stream per-thread ./stream_test.cu -o stream_per-thread  

图 2 显示了来自 nvvp 的结果。在这里可以看到九个流之间的完全并发:默认流(在本例中映射到流 14 )和创建的其他八个流。请注意,虚拟内核运行得如此之快,以至于很难看到在这个图像中默认流上有八个调用。

图 2 :使用新的每线程默认流选项的多流示例,它支持完全并发执行

在为并发进行编程时,还需要记住以下几点。

  • 记住:对于每线程的默认流,每个线程中的默认流的行为与常规流相同,只要同步和并发就可以了。对于传统的默认流,这是不正确的。
  • --default-stream 选项是按编译单元应用的,确保将其应用于所有需要它的 nvcc 命令行。
  • cudaDeviceSynchronize() 继续同步设备上的所有内容,甚至使用新的每线程默认流选项。如果只想同步单个流,请使用 cudaStreamSynchronize(cudaStream_t stream) ,如的第二个示例所示。
  • 从 CUDA 7 开始,还可以使用句柄 cudaStreamPerThread 显式地访问每线程的默认流,也可以使用句柄 cudaStreamLegacy 访问旧的默认流。请注意, cudaStreamLegacy 仍然隐式地与每个线程的默认流同步,如果碰巧在一个程序中混合使用它们。
  • 可以通过将 cudaStreamCreate() 标志传递给 cudaStreamCreate() 来创建不与传统默认流同步的非堵塞流 。

参考文献:

CUDA 7 Stream流简化并发性 - 吴建明wujianming - 博客园

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

CUDA Stream流并发性 的相关文章

  • 即使使用stream_set_blocking,PHP SSH2流内容仍为空?

    我正在开发一个工具 它使用 PECL SSH2 扩展通过 SSH2 从远程主机读取 iptables 配置 我能够成功连接到主机 进行身份验证并执行命令 我遇到的问题是有时该流不包含任何数据 Load the current firewal
  • 创建流而无需从中创建物理文件

    我需要创建一个包含服务器上存在的文档的 zip 文件 我使用 Net Package 类来执行此操作 并创建一个新的 Package 即 zip 文件 我必须具有物理文件或流的路径 我试图不创建一个实际的 zip 文件 而是创建一个存在于内
  • “计算能力”是什么意思? CUDA?

    我是CUDA编程新手 对此了解不多 您能告诉我 CUDA 计算能力 是什么意思吗 当我在大学服务器上使用以下代码时 它向我显示了以下结果 for device 0 device lt deviceCount device cudaDevic
  • 如果您不打算从自适应渲染中受益,那么使用 HtmlTextWriter 有什么好处吗?

    除了从替代设备的自适应渲染中受益之外 编写所有这些代码是否有意义 writer WriteBeginTag table writer WriteBeginTag tr writer WriteBeginTag td writer Write
  • CUDA素数生成

    当数据大小增加超过 260k 时 我的 CUDA 程序停止工作 它不打印任何内容 有人能告诉我为什么会发生这种情况吗 这是我的第一个 CUDA 程序 如果我想要更大的素数 如何在 CUDA 上使用大于 long long int 的数据类型
  • cuda cpu功能-gpu内核重叠

    我在尝试开发以练习 CUDA 的 CUDA 应用程序时遇到并发问题 我想通过使用 cudaMemecpyAsync 和 CUDA 内核的异步行为来共享 GPU 和 CPU 之间的工作 但我无法成功重叠 CPU 执行和 GPU 执行 它与主机
  • cuda 共享内存 - 结果不一致

    我正在尝试并行缩减以对 CUDA 中的数组求和 目前我传递一个数组来存储每个块中元素的总和 这是我的代码 include
  • 在linux上编译一个基本的OpenCV + Cuda程序

    我过去在linux上使用过opencv 但没有使用过cuda 几个月来我一直在与以下编译错误作斗争 在尝试了许多解决方案后 我放弃并使用 Windows 不过 我真的很想在 Linux 上工作 这是我用来编译 opencv gpu 网站上给
  • 如何在 Visual Studio 2010 中设置 CUDA 编译器标志?

    经过坚持不懈的得到error identifier atomicAdd is undefined 我找到了编译的解决方案 arch sm 20旗帜 但是如何在 VS 2010 中传递这个编译器标志呢 我已经尝试过如下Project gt P
  • 将 InputStream 转换为固定长度字符串的 Stream

    Like in 将 InputStream 转换为给定字符集的 Stream https stackoverflow com questions 30336257 convert inputstream into streamstring
  • 设置最大 CUDA 资源

    我想知道是否可以设置 CUDA 应用程序的最大 GPU 资源 例如 如果我有一个 4GB GPU 但希望给定的应用程序只能访问 2GB 如果它尝试分配更多 就会失败 理想情况下 这可以在进程级别或 CUDA 上下文级别上设置 不 目前没有允
  • 下面的代码是如何工作的?

    众所周知 cout 在 VS2010 中是无缓冲的 参见 Stephan Lavavej 的帖子 here http connect microsoft com VisualStudio feedback details 642876 st
  • Yocto for Nvidia Jetson 由于 GCC 7 而失败 - 无法计算目标文件的后缀

    我正在尝试将 Yocto 与 meta tegra 一起使用 https github com madisongh meta tegra https github com madisongh meta tegra 为 Nvidia Jets
  • 尝试构建我的 CUDA 程序时出现错误 MSB4062

    当我尝试构建我的第一个 GPU 程序时 出现以下错误 有什么建议可能会出什么问题吗 错误 1 错误 MSB4062 Nvda Build CudaTasks SanitizePaths 任务 无法从程序集 C Program 加载 文件 M
  • cuda中有模板化的数学函数吗? [复制]

    这个问题在这里已经有答案了 我一直在寻找 cuda 中的模板化数学函数 但似乎找不到 在普通的 C 中 如果我调用std sqrt它是模板化的 并且将根据参数是浮点数还是双精度数执行不同的版本 我想要这样的 CUDA 设备代码 我的内核将真
  • 将 ionic Zip 读取为内存流 C#

    我正在使用 Ionic Zip 通过以下方法将 ZipFile 提取到内存流 private MemoryStream GetReplayZipMemoryStream MemoryStream zipMs new MemoryStream
  • cudaSetDevice() 对 CUDA 设备的上下文堆栈有何作用?

    假设我有一个与设备关联的活动 CUDA 上下文i 我现在打电话cudaSetDevice i 会发生什么 Nothing 主上下文取代了堆栈顶部 主上下文被压入堆栈 事实上 这似乎是不一致的 我编写了这个程序 在具有单个设备的机器上运行 i
  • java套接字/输出流写入:它们会阻塞吗?

    如果我只写入输出流上的套接字 它会阻塞吗 只有读取才能阻塞 对吗 有人告诉我写入可以阻塞 但我只看到套接字读取方法的超时功能 Socket setSoTimeout 对我来说 写入可能会阻塞是没有意义的 如果我只写入输出流上的套接字 它会阻
  • 在java中将StreamWriter转换为OutputStream?

    我正在尝试使用 System setOut 将 System out 重定向到字符串 它需要一个 PrintStream 有什么方法可以将 StringWriter 转换为 Stream 以便我可以将其传递给 setOut 吗 你不能完全这
  • VS 程序在调试模式下崩溃,但在发布模式下不崩溃?

    我正在 VS 2012 中运行以下程序来尝试 Thrust 函数查找 include cuda runtime h include device launch parameters h include

随机推荐

  • 计划

    文档计划 读书的时候 2010年左右 由于和导师做了一些涉及单片机的项目 xff0c 狠狠熟悉了一把C语言 xff0c 所以试图写一个实时内核 xff0c 但是由于涉及大量的硬件知识 xff0c 底层汇编和任务栈之类的东西 xff0c 而这
  • CMOS内核--序言

    CMOS内核 序言 本文介绍一些CMOS中需要用的基础知识 由于在单片机系统中不会有MMU所以单片机系统中的每个任务就是一个线程 xff0c 共用系统的地址空间 xff0c 为了精确性 xff0c 后文中措辞中使用线程替换任务 xff0c
  • 欧拉角和旋转矩阵之间的转换

    一 什么是欧拉角 在3D 空间中 xff0c 表示物体的旋转可以由三个欧拉角来表示 xff1a pitch围绕X轴旋转 xff0c 叫俯仰角 yaw围绕Y轴旋转 xff0c 叫偏航角 roll围绕Z轴旋转 xff0c 叫翻滚角 这三个角的顺
  • C++编译之(1)-g++单/多文件/库的编译及C标准的发展历程

    g 43 43 编译入门 本文为您介绍g 43 43 的编译用法 xff1b 通过从最简单的单文件编译 xff0c 到多文件编译 xff0c 再到动态库 静态库的编译及使用 xff1b 例子都经过实际编译并运行 xff0c 可谓全网最良心之
  • STM32F103-寄存器开发-2

    上一篇博客中我已经配置好了对应的时钟 xff0c 接下来就是对GPIOC口进行操作了 为此我们需要配置端口配置寄存器 xff0c 但是在用户手册中查阅 xff0c 可以发现有两个寄存器 xff0c CRL和CRH xff0c 我们应该使用哪
  • 25.UART串口发送过程与配置

    UART串口收发过程与配置 参考资料 STM32Fx中文参考手册 第26章 xff1a 通用同步异步收发器章节 开发板配套教程 STM32Fx开发指南 串口实验章节 笔记基于正点原子官方视频 视频连接https www bilibili c
  • c语言HTTP服务器,超级简易版。

    算是对linux多线程的复习把 xff0c 尝试这用socket写了一个简单的HTTP服务器 xff0c 当访问它的时候它会给你发送一个HTML文件 xff0c 这个HTML文件需要自己写 代码 span class hljs prepro
  • linux POST请求

    linux POST请求 curl https baidu com X POST H key1 value1 H key2 value2 d name test age 23 i 说明 xff1a H header 后接key value对
  • CPPREST处理跨域问题

    本例使用的代码框架非常简单 按照下面这个路径搭建即可 https blog csdn net youyicc article details 108261287 问题由来 网页端需要动态检测C 服务器这边服务是否正常运行 所以采用的方式是h
  • 内存存取区——堆和栈

    一 预备知识 程序的内存分配 一个由c C 43 43 编译的程序占用的内存分为以下几个部分 1 栈区 xff08 stack xff09 由编译器自动分配释放 xff0c 存放函数的参数值 xff0c 局部变量的值等 其操作方式类似于数据
  • ROS中RVIZ坐标系及TF坐标系转换

    RVIZ坐标系 X轴 红色 Y轴 绿色 Z轴 蓝色 YAW 偏航角 绕Z轴旋转 PITCH 俯仰角 绕Y轴旋转 ROLL 滚转角 绕X轴旋转 符合右手坐标系原则 利用TF进行坐标系转换 采用以下指令进行转换 xff0c 其中frame id
  • 【C语言】长度为0的数组

    最近在看代码的时候发现一个好玩的事情 xff0c 长度为0的数组 xff0c 在此记录一下 在网上看到的这个说是只有GNU C才支持的特性 xff0c 因此考虑跨平台或者可移植特点需要慎用 话不多说 xff0c 上案例才有感觉 span c
  • jetson xavier nx使用usb线刷机后开机黑屏闪屏

    情况一 比较常见 xff09 由于刷机是的flash接口是调在右边的 xff0c 如下图所示 解决方法 xff1a 故在刷机成功后 xff0c 连接显示屏后要将flash接口调到 左侧 情况二 在对jetson xavier nxs进行刷机
  • python牛客网输入输出处理

    python 笔试输入 sys stdin readline和input 非常有用 xff01 xff01 xff09 https www jianshu com p 6f14ca3290ee input vs sys stdin read
  • Demo-简单使用libcurl静态库访问网址

    在开始前请先准备好下面的文件 xff1a 1 调试版的libcurl静态库libcurld lib xff0c 可以在网上下载或自己编译 xff1b 2 头文件 xff0c curl h curlver h easy h mprintf h
  • QQ 浏览器(iOS版)崩溃信息研究

    今天碰巧下载了QQ浏览器iOS版本 xff0c 居然一启动就挂了 后来从手机里面把崩溃信息导出来 xff0c 仔细研究下 xff0c 把研究的结果放到网上 xff0c 与大家分享下 先把我导出的崩溃信息放出来 Incident Identi
  • EXCEL利用VBA自由控制图表绘图区大小

    用好VBA的话确实可以给你再办公室的工作效率带来质的提升 如果有人跟你说你可以用Python什么的语言处理Excel balabala的 xff0c 你可以无视他了 当然python可以处理很多事情 xff0c 但是EXCEL自带的作图工具
  • 提升CUDA程序运行效率的几个关键点

    目录 1 明确计算机中GPU卡片的计算资源 xff0c 决定变量的性质 xff08 constant xff0c share还是global xff09 以及Grid xff0c Block的维度 xff0c 充分并合理利用GPU显卡的资源
  • CUDA程序编写具体参数设置

    介绍了GPU的结构以及资源的控制要素 xff08 GPU硬件结构和程序具体参数设置 yu132563的专栏 CSDN博客 xff09 以及编程过程中的一些需要注意的问题 xff08 CUDA程序性能调优 yu132563的专栏 CSDN博客
  • CUDA Stream流并发性

    目录 1 CUDA 中的异步命令 2 默认流 3 Multistream多流示例 异构计算是指高效地使用系统中的所有处理器 xff0c 包括 CPU 和 GPU 为此 xff0c 应用程序必须在多个处理器上并发执行函数 CUDA 应用程序通