目录

文章目录

  • 目录
  • GPGPU
  • CUDA 编程模型
  • CUDA 的架构
  • CUDA 的工作原理
    • Grid、Block、Thread
    • Warp

GPGPU

GPU 起初是用来处理图像的,但是后来人们发现其并行运算原理不仅可以用在图形渲染上,也可以推广到一般的运算中。于是 GPU 的功能就进行了升级,可以进行稍微复杂的工作了,并且可编程,也就有了 GPGPU(通用图形处理器)的概念。

GPGPU 其实是对 GPU 的一种优化,让 GPU 更加的具有易用性和通用型,GPU 应用于 ML/AI 就是 GPU 通用属性的一个方向,类似的方向有很多:挖矿、HPC 高性能计算等。

GPU 可以利用多个 CUDA Core / SP 来做并行计算,而 CPU 只能按照顺序进行串行计算,同样运行 3000 次的简单运算,CPU 需要 3000 个时钟周期,而配有 3000 个 CUDA 核心的 GPU 运行只需要 1 个时钟周期。

如果想用 GPU 做通用的计算,就要有更通用的编程工具。为此,很多针对 GPGPU 的并行计算架构就产生了,主要有 CUDA 和 OpenCL。

CUDA 编程模型

CUDA(Compute Unified Device Architecture,统一计算架构)是由 NVIDIA 在 2006 年推出的一种编程模型。是 NVIDIA 对于 GPGPU 的正式名称,本质是一种外部接口编程模型。

利用 CUDA 技术,使 GPGPU 能够解决复杂的计算问题。它包含了 CUDA ISA(指令集架构)以及 GPU 内部的并行计算引擎。开发人员现在可以使用 C 语言来为 CUDA 架构编写程序。CUDA 配合适当的软件(e.g. MediaCoder、Freemake Video Converter)就可以利用 GPU 进行高清视频编码加速、AI 训练等功能。

简而言之,CUDA 是获取 NVIDIA GPU 运算能力的开发平台,所有基于 G80 及之后架构的民用与专业显卡或运算模块皆支持 CUDA 技术。

CUDA 技术有下列几个优点:

  1. 分散读取:代码可以从存储器的任意地址读取。
  2. 统一虚拟内存。
  3. 共享存储器:CUDA 公开一个快速的共享存储区域,使之在多个进程之间共享。其作为一个用户管理的高速缓存,比使用纹理查找可以得到更大的有效带宽。
  4. 与 GPU 之间更快的加载与回读。
  5. 全面支持整型与位操作,包括整型纹理查找。

CUDA 的架构

CUDA 主要提供了 4 个重要的组件:

  • CUDA C:其实就是标准 C 的变种,它加入 4 大特性:

    • 可以定义程序的哪部分运行在 GPU 或 CPU 上;
    • 可以定义变量位于 GPU 的存储类型;
    • 利用 KERNEL、BLOCK、GRID 来定义最原始的并行计算;
    • State 变量。
  • CUDA 开发库:基于 CUDA 技术所提供的应用开发库。CUDA 的 1.1 版提供了两个标准的数学运算库:CUFFT(离散快速傅立叶变换)和 CUBLAS(离散基本线性计算)的实现。这两个数学运算库所解决的是典型的大规模的并行计算问题,也是在密集数据计算中非常常见的计算类型。开发人员在开发库的基础上可以快速、方便的建立起自己的计算应用。此外,开发人员也可以在 CUDA 的技术基础上实现出更多的开发库。

  • CUDA COMPILER/RUNTIME(编译器/运行时环境):提供了应用开发接口和运行期组件,包括基本数据类型的定义和各类计算、类型转换、内存管理、设备访问和执行调度等函数。基于 CUDA 开发的程序代码在实际执行中分为两种,一种是运行在 CPU 上的宿主代码(Host Code),一种是运行在 GPU 上的设备代码(Device Code)。不同类型的代码由于其运行的物理位置不同,能够访问到的资源不同,因此对应的运行期组件也分为公共组件、宿主组件和设备组件三个部分,基本上囊括了所有在 GPGPU 开发中所需要的功能和能够使用到的资源接口,开发人员可以通过运行期环境的编程接口实现各种类型的计算。

  • CUDA 驱动:由于目前存在着多种 GPU 版本的 NVIDIA 显卡,不同版本的 GPU 之间都有不同的差异,因此 CUDA 驱动基本上可以理解为是 CUDA-enable 的 GPU 的设备抽象层,提供硬件设备的抽象访问接口。CUDA 提供运行期环境也是通过这一层来实现各种功能的。由于体系结构中硬件抽象层的存在,CUDA 今后也有可能发展成为一个通用的 GPU 标准接口,兼容不同厂商的 GPU 产品。

对于软件开发者来说,使用 CUDA 平台调用 CUDA 的加速库使用的语言包括:C/C++ 和 Fortran。C/C++ 编程者使用 UDAC/C++ 并用 nvcc 进行编译。Nvidia 的 LLVM 库是基于 C/C++ 编译器的。Fortran 的开发者能够使用 CUDA Fortran,编译使用 PGI CUDA Fortran。

当然 CUDA 平台也支持其他的编程接口,包括 OpenCL,微软的 DirectCompute、OpenGL ComputeShaders 和 C++ AMP。第三方的开发者也可以使用 Python、Perl、Fortran、Java、Ruby、Lua、Haskell、R、MATLAB、IDL 由曼赛马提亚原生支持。

CUDA 的工作原理

在 CUDA 中,程序的执行区域分为 2 个部分:

  1. CPU(HOST Code)
  2. GPU(DEVICE Code)

任务组织和发送是在 CPU 里完成的,而并行计算是在 GPU 里完成。GPU 是协处理器,与 CPU 的 Main Memory 是分离的,故 GPU 运算时必须先将 CPU 端的代码和数据传输到 GPU,GPU 才能执行 kernel 函数。

一个典型的 GPU 设备的工作流程为:

  1. 应用层调用 GPU 支持的某个 OpenGL 或 CUDA API。
  2. OpenGL 或 CUDA 库,通过 UMD(User Mode Driver),提交 workload 到 KMD(Kernel Mode Driver)
  3. KMD 写 CSR MMIO,把它提交给 GPU 硬件。
  4. GPU 硬件开始工作,并在完成后,DMA 到内存,发出中断给 CPU。
  5. CPU 找到中断处理程序,由于 KMD 此前向 OS Kernel 注册过的,所以可以调用它。
  6. 中断处理程序找到是哪个 workload 被执行完毕了,最终驱动唤醒相关的应用。

而其中的数据流为:

  1. 将 Main Memory 的处理数据复制到 GPU Memory 中。
  2. CPU 指令驱动 GPU。
  3. GPU 中的每个运算单元并行处理。此步会从 GPU Memory 存取数据。
  4. GPU 将 GPU Memory 结果传回 Main Memory。

每当 CPU 遇到需要并行计算的任务,则将要做的运算组织成 kernel,然后丢给 GPU 去执行。当然任务是通过 CUDA 系统来丢的,CUDA 在把任务正式提交给 GPU 前,会对 kernel 做些处理,让 kernel 符合 GPU 体系架构。

假设,我们先简单的把 GPU 当作拥有上百个核的 CPU,kernel 当成一个要创建为线程的函数。所以,CUDA 现在就要将你的 kernel 创建出上百个 thread,然后将这些 thread 送到 GPU 中的各个核上去运行。

但为了更好的利用 GPU 资源,提高并行度,CUDA 还要将这些 thread 加以优化组织,将能利用共有资源的线程组织到一个 thread block 中,同一 thread block 中的 thread 可以通过 share memory 共享数据,每个 thread block 最高可拥有 512 个线程。拥有同样维度同样 kernel 的 thread block 被组织成一个 Grid,而 CUDA 处理任务的最大单元便是 Grid 了。

Grid、Block、Thread

利用 CUDA 进行编程时,一个 GRID 分为多个 Block,而一个 Block 可分为多个 Thread。

  • 多个 Blocks 可以组成 1 维、2 维或者 3 维的 Grid。kernel 函数可以访问 Grid 内部标识 Block 的内置变量 BlockIDX,也可以访问表示 Block 维度的内置变量 BlockDim。

  • 每个 Block 所能包含的 Thread 数量是有限制的,因为目前每个 Block 内的所有 Threads 都是在一个物理的处理器核中,并且共享了这个核有限的内存资源。当前的 GPU 中,每个 Block 最多能执行 1024 个 Thread。

Warp

Warp 是 GPU 执行程序时的调度单位,目前 CUDA 的 Warp 大小为 32,同在一个 Warp 的线程,以不同数据资源执行相同的指令。

  • Warp 调度单元与 Threads 的关系

上图反映了 Warp 作为调度单位的作用,每次 GPU 调度一个 Warp 里的 32 个线程执行同一条指令,其中各个线程对应的数据资源不同。

上图反映了 Warp 是如何排程的,即最终将 CUDA thread 映射到实际的物理硬件计算单元中执行(Thread => SP Block => SM Grid => GPU)。

一个 SM 只会执行一个 Block 里的 Warp,当该 Block 里 Warp 执行完后才会执行其他 Block 里的 Warp。进行划分时,最好保证每个 Block 里的 Warp 数量合理,那样一个 SM 可以交替执行里面的 Warp,从而提高效率。

此外,在分配 Block 时,要根据 GPU 的 SM 个数,分配出合理的 Block 数,让 GPU 的 SM 都利用起来,提利用率。分配时,也要考虑到同一个线程 Block 的资源问题,不要出现对应的资源不够。

CUDA threads 在执行时,可以访问多个 Memory Spaces,每个线程有自己的私有的 Local Memory。每个 Block 有一个 Shared Memory,Block 的所有线程都可以访问。

最后,所有线程都可以访问 Global Memory。不同的内存访问速度为:本地内存 > 共享内存 > 全局内存。

通过 cudaMalloc 函数分配的内存就是全局内存。核函数中用 shared 修饰的变量就是共享内存。 核函数定义的变量使用的就是本地内存。

GPU — CUDA 编程模型相关推荐

  1. CUDA刷新器:CUDA编程模型

    CUDA刷新器:CUDA编程模型 CUDA Refresher: The CUDA Programming Model CUDA,CUDA刷新器,并行编程 这是CUDA更新系列的第四篇文章,它的目标是 ...

  2. cuda编程_CUDA刷新器:CUDA编程模型

    CUDA刷新器:CUDA编程模型 CUDA Refresher: The CUDA Programming Model CUDA,CUDA刷新器,并行编程 这是CUDA更新系列的第四篇文章,它的目标是 ...

  3. CUDA C 编程指导(二):CUDA编程模型详解

    CUDA编程模型详解 本文以vectorAdd为例,通过描述C在CUDA中的使用(vectorAdd这个例子可以在CUDA sample中找到.)来介绍CUDA编程模型的主要概念.CUDA C的进一步 ...

  4. cuda C 编程权威指南 Grossman 第2章 CUDA编程模型

    2.1 CUDA编程模型概述 CUDA编程模型提供了一个计算机架构抽象作为应用程序和其可用硬件之间的桥梁. 通信抽象是程序与编程模型实现之间的分界线,它通过专业的硬件原语和操作系统的编译器或库来实现. ...

  5. GPU及GPU通用计算编程模型简介

    以下内容来自网络总结: NVIDIA公司在1999年发布GeForce256时首先提出GPU(图形处理器)的概念,随后大量复杂的应用需求促使整个产业蓬勃发展至今. GPU英文全称Graphic Pro ...

  6. [人工智能-深度学习-40]:英伟达GPU CUDA 编程框架简介

    作者主页(文火冰糖的硅基工坊):文火冰糖(王文兵)的博客_文火冰糖的硅基工坊_CSDN博客 本文网址:https://blog.csdn.net/HiWangWenBing/article/detai ...

  7. CUDA C编程权威指南 第二章 CUDA编程模型

    CUDA6.0开始 有"统一寻址"(Unified Memory)编程模型,可以用单个指针访问CPU和GPU内存,无须手动拷贝 主机启动内核后,管理权立刻返回给主机(类似启动线程后 ...

  8. GPU硬件结构和编程模型(源于nvidia的CUDA文档)

    GPU的硬件结构 GPU通过一个可扩展的多线程流式多处理器(SMs)构建.一个multiprocessor可以在同一时间处理上百个线程.为了管理这些线程,使用一个特殊的结构SIMT.利用单线程中指令级 ...

  9. CUDA编程之快速入门-----GPU加速原理和编程实现

    转载:https://www.cnblogs.com/skyfsm/p/9673960.html CUDA(Compute Unified Device Architecture)的中文全称为计算统一 ...

最新文章

  1. 阿联酋gitex_航空公司网站不在乎您的隐私后续行动:阿联酋航空以以下方式回应我的文章:...
  2. 关于ACM写给自己啦
  3. book mac pro怎么重装系统_Macbook Pro怎么重装系统
  4. js修改mysql数据库数据_Node.js操作mysql数据库增删改查
  5. Oracle开发›如何取出每个分组的第一条记
  6. TCP/IP 详解笔记
  7. 从团购的“占便宜”心态说起
  8. 行为型模式——模板方法模式
  9. gaussian09使用教程linux,Gaussian-09-GaussView5.0使用教程.ppt
  10. mysql如何批量添加数据_mysql如何大批量插入数据 mysql大批量插入数据4种方法
  11. WiFi共享大师 去广告
  12. 1 年原创 150+ 篇,这位前阿里 P9 牛批!
  13. 汉语计算机语言,从计算机编程语言说汉语的比较优势
  14. Android开发:登录/注册界面的编写
  15. EXCEL如何实现两个表的相应数据关联
  16. 电子邮件营销中的邮件主题设计
  17. Flink之DataSet迭代计算
  18. 如何破解PDF文档不能打印?
  19. 经典力学中最难的问题,至今没有答案
  20. 找不到或无法加载主类com.kuang.springcloud.DeptProvider_8002

热门文章

  1. python变量类型之间转换_Python变量赋值类型转换
  2. XamarinSQLite教程创建数据表
  3. Ie html button消失,input 按钮在IE下兼容问题
  4. jira 审批流程_博兴县行政审批服务局推暖心服务工程 企业开办实现“全程网办”_博兴新闻...
  5. 解码大脑:在脑机接口上寻求稳定性
  6. Python-Evoked地形图可视化
  7. BCI比赛数据集简介-BCI competition IV 2b
  8. Vulkan统一所有平台的API
  9. ios 裁剪框大小_iOS实现裁剪框和图片剪裁功能
  10. 机器人用上AI后,拥有了堪比人类皮肤的触觉:轻松引线穿针、夹取鸡蛋丨Science子刊...