0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

CUDA编程模型如何在c++实现

星星科技指导员 来源:NVIDIA 作者:Ken He 2022-04-21 16:13 次阅读

本章通过概述CUDA编程模型是如何在c++中公开的,来介绍CUDA的主要概念。

NVIDIA GPU 架构围绕可扩展的多线程流式多处理器 (SM: Streaming Multiprocessors) 阵列构建。当主机 CPU 上的 CUDA 程序调用内核网格时,网格的块被枚举并分发到具有可用执行能力的多处理器。一个线程块的线程在一个SM上并发执行,多个线程块可以在一个SM上并发执行。当线程块终止时,新块在空出的SM上启动。

SM旨在同时执行数百个线程。为了管理如此大量的线程,它采用了一种称为 SIMT(Single-Instruction, Multiple-Thread: 单指令,多线程)的独特架构,在 SIMT 架构中进行了描述。这些指令是流水线的,利用单个线程内的指令级并行性,以及通过同时硬件多线程处理的广泛线程级并行性,如硬件多线程中详述。与 CPU 内核不同,它们是按顺序发出的,没有分支预测或推测执行。

SIMT 架构和硬件多线程描述了所有设备通用的流式多处理器的架构特性。 Compute Capability 3.x、Compute Capability 5.x、Compute Capability 6.x 和 Compute Capability 7.x 分别为计算能力 3.x、5.x、6.x 和 7.x 的设备提供了详细信息

NVIDIA GPU 架构使用 little-endian 表示。

4.1 SIMT 架构

多处理器以 32 个并行线程组(称为 warp)的形式创建、管理、调度和执行线程。组成 warp 的各个线程一起从同一个程序地址开始,但它们有自己的指令地址计数器和寄存器状态,因此可以自由地分支和独立执行。warp一词源于编织,这是第一个并行线程技术。半warp是warp的前半部分或后半部分。四分之一经线是warp的第一、第二、第三或第四四分之一。

当一个多处理器被赋予一个或多个线程块来执行时,它将它们划分为warp,并且每个warp都由warp调度程序调度以执行。一个块被分割成warp的方式总是一样的;每个warp包含连续的线程,增加线程ID,第一个warp包含线程0。线程层次结构描述了线程ID如何与块中的线程索引相关。

一个 warp 一次执行一条公共指令,因此当一个 warp 的所有 32 个线程都同意它们的执行路径时,就可以实现完全的效率。如果 warp 的线程通过依赖于数据的条件分支发散,则 warp 执行所采用的每个分支路径,禁用不在该路径上的线程。分支分歧只发生在一个warp内;不同的 warp 独立执行,无论它们是执行公共的还是不相交的代码路径。

SIMT 体系结构类似于 SIMD(单指令多数据)向量组织,其中单指令控制多个处理元素。一个关键区别是 SIMD 矢量组织向软件公开了 SIMD 宽度,而 SIMT 指令指定单个线程的执行和分支行为。与 SIMD 向量机相比,SIMT 使程序员能够为独立的标量线程编写线程级并行代码,以及为协调线程编写数据并行代码。为了正确起见,程序员基本上可以忽略 SIMT 行为;但是,通过代码很少需要warp中的线程发散,可以实现显着的性能改进。在实践中,这类似于传统代码中缓存线的作用:在设计正确性时可以安全地忽略缓存线大小,但在设计峰值性能时必须在代码结构中考虑。另一方面,向量架构需要软件将负载合并到向量中并手动管理分歧。

在 Volta 之前,warp 使用在 warp 中的所有 32 个线程之间共享的单个程序计数器以及指定 warp 的活动线程的活动掩码。结果,来自不同区域或不同执行状态的同一warp的线程无法相互发送信号或交换数据,并且需要细粒度共享由锁或互斥锁保护的数据的算法很容易导致死锁,具体取决于来自哪个warp竞争线程。

从 Volta 架构开始,独立线程调度允许线程之间的完全并发,而不管 warp。使用独立线程调度,GPU 维护每个线程的执行状态,包括程序计数器和调用堆栈,并且可以在每个线程的粒度上产生执行,以便更好地利用执行资源或允许一个线程等待数据由他人生产。调度优化器确定如何将来自同一个 warp 的活动线程组合成 SIMT 单元。这保留了与先前 NVIDIA GPU 一样的 SIMT 执行的高吞吐量,但具有更大的灵活性:线程现在可以在 sub-warp 粒度上发散和重新收敛。

如果开发人员对先前硬件架构的 warp-synchronicity2 做出假设,独立线程调度可能会导致参与执行代码的线程集与预期的完全不同。特别是,应重新访问任何warp同步代码(例如无同步、内部warp减少),以确保与 Volta 及更高版本的兼容性。有关详细信息,请参阅计算能力 7.x。

注意:

参与当前指令的 warp 线程称为活动线程,而不在当前指令上的线程是非活动的(禁用)。线程可能由于多种原因而处于非活动状态,包括比其 warp 的其他线程更早退出,采用与 warp 当前执行的分支路径不同的分支路径,或者是线程数不是线程数的块的最后一个线程warp尺寸的倍数。

如果 warp 执行的非原子指令为多个 warp 的线程写入全局或共享内存中的同一位置,则该位置发生的序列化写入次数取决于设备的计算能力(参见 Compute Capability 3.x、Compute Capability 5.x、Compute Capability 6.x 和 Compute Capability 7.x),哪个线程执行最终写入是未定义的。

如果一个由 warp 执行的原子指令读取、修改和写入全局内存中多个线程的同一位置,则对该位置的每次读取/修改/写入都会发生并且它们都被序列化,但是它们发生的顺序是不确定的。

4.2 硬件多线程

多处理器处理的每个 warp 的执行上下文(程序计数器、寄存器等)在 warp 的整个生命周期内都在芯片上维护。因此,从一个执行上下文切换到另一个执行上下文是没有成本的,并且在每个指令发出时,warp 调度程序都会选择一个线程准备好执行其下一条指令(warp 的活动线程)并将指令发布给这些线程。

特别是,每个多处理器都有一组 32 位寄存器,这些寄存器在 warp 之间进行分区,以及在线程块之间进行分区的并行数据缓存或共享内存。

对于给定内核,可以在多处理器上一起驻留和处理的块和warp的数量取决于内核使用的寄存器和共享内存的数量以及多处理器上可用的寄存器和共享内存的数量。每个多处理器也有最大数量的驻留块和驻留warp的最大数量。这些限制以及多处理器上可用的寄存器数量和共享内存是设备计算能力的函数,在附录计算能力中给出。如果每个多处理器没有足够的寄存器或共享内存来处理至少一个块,内核将无法启动。

一个块中的warp总数如下:

pYYBAGJhEkOAPzJ8AABJQgzZJ1g200.png

为块分配的寄存器总数和共享内存总量记录在 CUDA 工具包中提供的 CUDA Occupancy Calculator中。

关于作者

Ken He 是 NVIDIA 企业级开发者社区经理 & 高级讲师,拥有多年的 GPU 和人工智能开发经验。自 2017 年加入 NVIDIA 开发者社区以来,完成过上百场培训,帮助上万个开发者了解人工智能和 GPU 编程开发。在计算机视觉,高性能计算领域完成过多个独立项目。并且,在机器人无人机领域,有过丰富的研发经验。对于图像识别,目标的检测与跟踪完成过多种解决方案。曾经参与 GPU 版气象模式GRAPES,是其主要研发者。

审核编辑:郭婷

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 机器人
    +关注

    关注

    210

    文章

    28197

    浏览量

    206510
  • NVIDIA
    +关注

    关注

    14

    文章

    4936

    浏览量

    102812
  • gpu
    gpu
    +关注

    关注

    28

    文章

    4700

    浏览量

    128697
收藏 人收藏

    评论

    相关推荐

    C++新手容易犯的十个编程错误

    简单的总结一下 C++ 新手容易犯的一些编程错误,给新人们提供一个参考。 1 有些关键字在 cpp 文件中多写了 对于 C++ 类,一些关键字只要写在 .h 中就好,cpp 中就不用再加上了,比如
    的头像 发表于 11-15 12:42 205次阅读

    C++实现类似instanceof的方法

    函数,可实际上C++中没有。但是别着急,其实C++中有两种简单的方法可以实现类似Java中的instanceof的功能。 在 C++ 中,确定对象的类型是
    的头像 发表于 07-18 10:16 534次阅读
    <b class='flag-5'>C++</b>中<b class='flag-5'>实现</b>类似instanceof的方法

    FX2 CY7C68013A如何在C++环境中使用LoadEEPROM函数?

    我使用的是 FX2 CY7C68013A 芯片。 我知道 CyUSB.NET 库中有我需要的 LoadEEPROM 函数。 请问如何在 C++ 环境而不是 C#/CLR 环境中使用该函
    发表于 05-31 06:59

    何在FX3 SuperSpeed explorer等电路板上使用openOCD调试C++项目?

    配置与文档中的完全相同。 因此,我想请教如何在 FX3 SuperSpeed explorer 等电路板上使用 openOCD 调试我的 C++ 项目? 回到纯 C 项目并不是一个真正的选择,而且仅通过 uart 进行调试是不够
    发表于 05-23 08:16

    鸿蒙OS开发实例:【Native C++

    使用DevEco Studio创建一个Native C++应用。应用采用Native C++模板,实现使用NAPI调用C标准库的功能。使用C
    的头像 发表于 04-14 11:43 2504次阅读
    鸿蒙OS开发实例:【Native <b class='flag-5'>C++</b>】

    为什么很少用C++开发单片机

    C语言是面向过程的语言,C++是面向对象的编程语言。结合本文来说,面向过程相比面向对象的编程,生成代码量(bin文件)更小,运行效率更高。
    发表于 03-25 14:26 832次阅读
    为什么很少用<b class='flag-5'>C++</b>开发单片机

    CY8C624AAZI-S2D44如何在PSoC Creator4.4中实现编程开发?

    CY8C624AAZI-S2D44如何在PSoC Creator4.4实现编程开发?
    发表于 03-05 06:17

    c语言,c++,java,python区别

    C语言、C++、Java和Python是四种常见的编程语言,各有优点和特点。 C语言: C语言是一种面向过程的
    的头像 发表于 02-05 14:11 2234次阅读

    vb语言和c++语言的区别

    VB语言和C++语言是两种不同的编程语言,虽然它们都属于高级编程语言,但在设计和用途上有很多区别。下面将详细比较VB语言和C++语言的区别。 设计目标: VB语言(Visual Bas
    的头像 发表于 02-01 10:20 2058次阅读

    基于QT5+OpenCV+OpenVINO C++的应用打包过程

    我用QT C++写了一个YOLOv5模型推理演示应用。
    的头像 发表于 01-26 10:17 1134次阅读
    基于QT5+OpenCV+OpenVINO <b class='flag-5'>C++</b>的应用打包过程

    C++简史:C++是如何开始的

    的 MISRA C++:2023 博客系列的第二部分。 在这篇博客中,我们将深入探讨 C++ 的历史、编程语言多年来的发展历程以及它的下一步发展方向。
    的头像 发表于 01-11 09:00 536次阅读
    <b class='flag-5'>C++</b>简史:<b class='flag-5'>C++</b>是如何开始的

    【飞腾派4G版免费试用】第五章:使用C++部署tflite模型到飞腾派

    本章记录下使用 C++ 进行佩奇检测 tflite 模型推理的过程。
    的头像 发表于 12-28 09:08 1217次阅读
    【飞腾派4G版免费试用】第五章:使用<b class='flag-5'>C++</b>部署tflite<b class='flag-5'>模型</b>到飞腾派

    OpenCV4.8 CUDA编程代码教程

    OpenCV4支持通过GPU实现CUDA加速执行,实现对OpenCV图像处理程序的加速运行,当前支持加速的模块包括如下。
    的头像 发表于 12-05 09:56 985次阅读
    OpenCV4.8 <b class='flag-5'>CUDA</b><b class='flag-5'>编程</b>代码教程

    如何选择创建c语言和c++

    选择创建 C 语言和 C++ 都需要综合考虑多个因素。在决定使用哪种语言之前,我们需要对这两种语言的特点、优缺点、适用场景、学习成本等进行全面的了解和对比。下面是关于选择创建 C 语言和 C+
    的头像 发表于 11-27 15:58 569次阅读

    c++怎么开始编程

    C++是一种高级的、通用的编程语言,用于开发各种类型的应用程序。它是从C语言演变而来,也是一种静态类型语言,可以在不同的平台上进行开发。C++具有高度的灵活性和性能,并且广泛应用于游戏
    的头像 发表于 11-27 15:56 894次阅读