Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >CUDA 基础 01 - 概念

CUDA 基础 01 - 概念

作者头像
叉叉敌
发布于 2022-09-28 08:05:56
发布于 2022-09-28 08:05:56
56000
代码可运行
举报
文章被收录于专栏:ChasaysChasays
运行总次数:0
代码可运行

最近在GPU编译器测试方面遇到一些瓶颈,准备学习下cuda 相关的基础知识。

warp/sm/index/grid等。

CPU VS GPU

GPU最重要的一点是可以并行的实现数据处理。

这一点在数据量大、运算复杂度不高的条件下极为适用。可以简单地把一块GPU想象成一个超多核的CPU运算部件。这些CPU有自己的寄存器,还有供数据交换用的共享内存、缓存,同时周围还有取指部件和相应的调度机制,保证指令能够在之上执行。

这里有一张典型的CPU和GPU的对比图片,CPU和GPU就呈现出非常不同的架构

  • 鲜绿色:计算单元ALU(Arithmetic Logic Unit)
  • 橙红色:存储单元(cache)
  • 橙黄色:控制单元(control)

GPU:数量众多的计算单元和超长的流水线,只有简单的控制逻辑并省去了Cache CPU:被Cache占据了大量空间,而且还有有复杂的控制逻辑和诸多优化电路。

这个比喻就很恰当:

GPU的工作大部分就是这样,计算量大,而且要重复很多很多次。就像你有个工作需要算几亿次一百以内加减乘除一样,最好的办法就是雇上几十个小学生一起算,一人算一部分 CPU就像老教授,积分微分都会算,就是工资高,一个老教授资顶二十个小学生,你要是富士康你雇哪个 CPU和GPU因为最初用来处理的任务就不同,所以设计上有不小的区别,而某些任务和GPU最初用来解决的问题比较相似,所以用GPU来算了。

软件

grid 概念

CUDA 采用异构编程模型,用于运行主机设备应用程序。它有一个类似于 OpenCL 的执行模型。在这个模型中,我们开始在主机设备上执行一个应用程序,这个设备通常是 CPU 核心。该设备是一个面向吞吐量的设备,也就是说,一个 GPU 核心执行并行计算。内核函数用于执行这些并行执行。一旦执行了这些内核函数,控制就被传递回继续执行串行操作的主机设备。

为了方便定位threadidx等,用多维数据来表示,就有了维度。

由于许多并行应用程序涉及多维数据,因此可以很方便地将线程块组织成一维、二维或三维线程数组。grid中的块必须能够独立执行,因为grid中的块之间不可能进行通信或合作。当启动一个内核时,每个线程块的线程数量,并且指定了线程块的数量,这反过来又定义了所启动的 CUDA 线程的总数。

块的最大 x、 y 和 z 维分别为1024、1024和64,其分配应使 x × y × z ≤1024,即每个块的最大线程数。

扩展理解:float4, int4, long4 又是什么?有什么好处?

index 索引

CUDA 中的每个线程都与一个特定的索引相关联,因此它可以计算和访问数组中的内存位置。

举个例子:

其中有一个512个元素的数组。其中一种组织结构是使用一个包含512个线程的单个块的grid。假设有一个由512个元素组成的数组 C,它由两个数组 A 和 B 的元素相乘构成,这两个数组都是512个元素。每个线程都有一个索引 i,它执行 A 和 B 的第 i 个元素的乘法运算,然后将结果存储在 C 的第 i 个元素中。 i 是通过使用 blockIdx (在这种情况下是0,因为只有一个块)、 blockDim (在这种情况下是512,因为块有512个元素)和 threadIdx 计算得到的,每个块的值从0到511不等。

线程索引 i 按以下公式计算:

int i = blockIdx.x * blockDim.x + threadIdx.x;

因此,i的值范围从0到511,覆盖整个数组。但是不一定是连续的,3,4,1,2。。。。

再来:

考虑一个大于1024的数组的计算,我们可以有多个块,每个块有1024个线程。考虑一个包含2048个数组元素的示例。在这种情况下,我们有2个线程块,每个线程有1024个线程。因此线程标识符的值将从0到1023不等,块标识符将从0到1不等,块维度将为1024。因此,第一个块将获得从0到1023的索引值,最后一个块将获得从1024到2047的索引值。

每个线程将首先计算它必须访问的内存索引,然后继续进行计算。举个实际的例子,其中数组 A 和 B 的元素通过使用线程并行添加,结果存储在数组 C 中。线程中相应的代码如下所示

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
__global__ void vectorAdd (float 

*A , float *B , float * C , int n) { int index = blockIdx.x *

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
blockDim.x + threadIdx.x;
    if (index < n)
    {
        C[index] = A[index] + 

B[index] ; } }

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
除了一维还有2/3维度,计算index可以参考公式,也是一样不一定连续, 234,235,200,201......

硬件
==

SM stream Multiprocessor: 流多处理器
-------------------------------

每个SM内又包括了多个SP(streaming processor)。而SP正是实现算数功能的核心部件,可以类比CPU之中的ALU单元,只不过其计算能力要差很多。

![图片](https://img-blog.csdnimg.cn/img_convert/083fc45aefe44f987f017e1416c622c3.png)

可以看到,每个SM内部的SP之间,可以共享一块shared memory。

以及一块指令缓存用于存放指令、一块常量缓存(c-cache)用来存放常量数据,两个SFU(特殊运算单元,special function unit)用来做三角函数等较复杂运算,MT issue用来实现多线程下的取指,以及DP(Double Precision Unit)用来做双精度数。 除去一些运算单元之外,最重要的就是c-cache与shared memory两块数据存储区。`注意这两个位置的数据只能由SM内部的SP进行访问`SM之间也有用于数据交换的区域。最主要的是global memory。

硬件将线程块调度到一个 SM。一般来说,SM 可以同时处理多个线程块。一个 SM 可能总共包含多达8个线程块。线程 ID 由其各自的 SM 分配给线程。

每当 SM 执行一个线程块时,线程块中的所有线程都同时执行。因此,为了释放 SM 内部线程块的内存,关键是该块中的整个线程集都已结束执行。每个线程块被划分为预定的单元,称为warp。

warp (wave、wavefront)
---------------------

不同GPU vendor叫法不一样,A卡叫wave,N卡叫warp/卧铺/,我司的也叫wave。我个人理解的就是一波波的相同指令的线程执行,wave好记。

Warp:warp是SM调度和执行的基础概念,通常一个SM中的SP(thread)会分成几个warp(也就是SPSM中是进行分组的,物理上进行的分组),一般每一个WARP中有32个thread.这个WARP中的32个thread(sp)是一起工作的,执行相同的指令,如果没有这么多thread需要工作,那么这个WARP中的一些thread(sp)是不工作的,叫inactive。

我们应该注意,`线程、线程块和grid本质上是编程的视角`。为了得到一个完整的线程块要点,从硬件的角度了解它是至关重要的。硬件将执行相同指令的线程分组为 `warps` 。几个warps组成一个线程块。几个线程块被分配给一个流式多处理器(SM)。几个 SM 组成了整个 GPU 单元(执行整个内核grid)。

编程的视角与 GPU 中线程块的硬件视角之间的图形关联。

![图片](https://img-blog.csdnimg.cn/img_convert/46bb19fa0941ba3a01ce0bd9542e6b8a.png)

在硬件方面,线程块由“warp”组成。warp是一个线程块中的32个线程的集合,使得warp中的所有线程执行相同的指令。这些线程由 SM 连续选择。

假设有32个执行指令的线程。如果其中一个或两个操作数都没有准备好(例如还没有从全局内存中获取) ,就会发生一个称为“上下文切换”的过程,将控制权转移到另一个指定的操作数上。

当从一个特定的warp切换时,warp的所有数据都保留在寄存器文件中,以便在其操作数准备就绪时能够迅速恢复。当一条指令没有突出的数据依赖关系时,也就是说,它的两个操作数都准备好了,就认为各自的偏差已经准备好可以执行了。如果有多个warp符合执行条件,则父 SM 使用一个warp调度策略来决定哪个warp获取下一个提取指令。

> warp调度有不同的策略,这个有点深入,先不看,加个#TODO。比如RRLRFFAIRCAWS。

Read more
---------

https://en.wikipedia.org/wiki/Thread\_block\_(CUDA\_programming)

https://www.nvidia.com/content/PDF/fermi\_white\_papers/NVIDIA\_Fermi\_Compute\_Architecture\_Whitepaper.pdf

http://www.uml.org.cn/embeded/201809034.asp?artid=21130

https://www.cnblogs.com/maomaozi/p/15939275.html
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-09-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
cuda教程[新手入门学编程]
大家好,我是架构君,一个会写代码吟诗的架构师。今天说一说cuda教程[新手入门学编程],希望能够帮助大家进步!!!
Java架构师必看
2022/03/22
3.1K0
cuda教程[新手入门学编程]
AI部署篇 | CUDA学习笔记2:矩阵乘法与GPU优化(附CUDA代码)
获得 C 矩阵的计算方法都是相同的,只不过使用的是矩阵 A、B 不同的元素来进行计算,即不同数据的大量相同计算操作,这种计算是特别适合使用GPU来计算,因为GPU拥有大量简单重复的计算单元,通过并行就能极大的提高计算效率。
集智书童公众号
2022/02/10
6K0
AI部署篇 | CUDA学习笔记2:矩阵乘法与GPU优化(附CUDA代码)
【AI系统】SIMD & SIMT 与芯片架构
为了进一步探讨 SIMD/SIMT 与 AI 芯片之间的关系,本文将详细介绍 SIMD 单指令多数据和 SIMT 单指令多线程的计算本质,以及对 NVIDIA CUDA 底层实现 SIMD/SIMT 的原理进行讲解。
用户11307734
2024/11/27
1620
CUDA是什么-CUDA简介「建议收藏」
在大家开始深度学习时,几乎所有的入门教程都会提到CUDA这个词。那么什么是CUDA?她和我们进行深度学习的环境部署等有什么关系?通过查阅资料,我整理了这份简洁版CUDA入门文档,希望能帮助大家用最快的时间尽可能清晰的了解这个深度学习赖以实现的基础概念。
全栈程序员站长
2022/09/02
5.9K0
AI部署篇 | CUDA学习笔记1:向量相加与GPU优化(附CUDA C代码)
GPU并不是一个独立运行的计算平台,而需要与CPU协同工作,也可以把GPU看成是CPU的协处理器,因此当在说GPU并行计算时,其实是指的基于CPU+GPU的异构计算架构。在异构计算架构中,GPU与CPU通过PCIe总线连接在一起进行协同工作,CPU所在位置称为为主机端(host),而GPU所在位置称为设备端(device),如下图所示。
集智书童公众号
2022/01/05
2.9K0
AI部署篇 | CUDA学习笔记1:向量相加与GPU优化(附CUDA C代码)
CUDA编程之线程模型
一个kernel结构如下:Kernel<<>>(param1, param2, …)
AI异构
2020/07/29
2.8K0
CUDA编程之线程模型
【参加CUDA线上训练营】--CUDA编程模型线程组织
GPU在管理线程的时候是以block为单元调度到SM上执行,每个block中以warp作为一次执行的单位,每个warp包括32个线程。
云帆沧海
2024/01/17
2050
【参加CUDA线上训练营】--CUDA编程模型线程组织
Python CUDA 编程 - 3 - GPU编程介绍
以加法计算为例,CPU就像大学数学教授,GPU就像几千个小学生,现在需要不借助外界,只通过纸笔,对2000个数字进行加法计算,得到1000个加法结果,在这个过程中,大学教授要协调指挥小学生完成任务。
为为为什么
2022/08/04
1.9K0
Python CUDA 编程 - 3 - GPU编程介绍
快来操纵你的GPU| CUDA编程入门极简教程
2006年,NVIDIA公司发布了CUDA(http://docs.nvidia.com/cuda/),CUDA是建立在NVIDIA的CPUs上的一个通用并行计算平台和编程模型,基于CUDA编程可以利用GPUs的并行计算引擎来更加高效地解决比较复杂的计算难题。近年来,GPU最成功的一个应用就是深度学习领域,基于GPU的并行计算已经成为训练深度学习模型的标配。目前,最新的CUDA版本为CUDA 9。
机器学习算法工程师
2018/07/27
5.1K0
快来操纵你的GPU| CUDA编程入门极简教程
如何高效实现矩阵乘?万文长字带你从CUDA初学者的角度入门
矩阵乘作为目前神经网络计算中占比最大的一个部分,其快慢会显著影响神经网络的训练与推断所消耗的时间。虽然现在市面上已经有非常多的矩阵乘的高效实现——如基于 cpu 的 mkl、基于 arm 设备的 ncnn 与 emll、基于 cuda 的 cublas ——掌握了矩阵乘优化的思路不仅能帮助你更好的理解编写高性能代码的一些基本原则,而且许多神经网络加速领域进阶的技巧如算子融合都是与矩阵乘交互从而达到更高的性能。
机器之心
2022/12/16
2.8K1
如何高效实现矩阵乘?万文长字带你从CUDA初学者的角度入门
从头开始进行CUDA编程:Numba并行编程的基本概念
PU(图形处理单元)最初是为计算机图形开发的,但是现在它们几乎在所有需要高计算吞吐量的领域无处不在。这一发展是由GPGPU(通用GPU)接口的开发实现的,它允许我们使用GPU进行通用计算编程。这些接口中最常见的是CUDA,其次是OpenCL和最近刚出现的HIP。
deephub
2023/01/18
1.4K0
《GPU高性能编程 CUDA实战》(CUDA By Example)读书笔记
写在最前 这本书是2011年出版的,按照计算机的发展速度来说已经算是上古书籍了,不过由于其简单易懂,仍旧被推荐为入门神书。先上封面: 由于书比较老,而且由于学习的目的不同,这里只介绍了基础
用户1148523
2018/01/09
2.9K0
《GPU高性能编程 CUDA实战》(CUDA By Example)读书笔记
【AI系统】从 CUDA 对 AI 芯片思考
从技术的角度重新看英伟达生态,有很多值得借鉴的方面。本文将主要从流水编排、SIMT 前端、分支预测和交互方式等方面进行分析,同时对比 DSA 架构,思考可以从英伟达 CUDA 中借鉴的要点。
用户11307734
2024/11/27
1170
GPU加速02:超详细Python Cuda零基础入门教程,没有显卡也能学!
Python是当前最流行的编程语言,被广泛应用在深度学习、金融建模、科学和工程计算上。作为一门解释型语言,它运行速度慢也常常被用户诟病。著名Python发行商Anaconda公司开发的Numba库为程序员提供了Python版CPU和GPU编程工具,速度比原生Python快数十倍甚至更多。使用Numba进行GPU编程,你可以享受:
PP鲁
2019/12/26
6.8K0
GPU加速02:超详细Python Cuda零基础入门教程,没有显卡也能学!
cuda编程知识普及
本帖经过多方整理,大多来自各路书籍《GPGPU编程技术》《cuda高性能》 1 grid 和 block都可以用三元向量来表示: grid的数组元素是block   block的数组元素是grid 但是1.x计算能力的核心,grid的第三元必须为1.block的X和Y索引最大尺寸为512 2 通过__launch_bounds__(maxBlockSize,minBlocksPerMp)来限制每个block中最大的线程数,及每个多处理器上最少被激活的block数 3 SM streaming multip
用户1154259
2018/01/17
1.1K0
cuda编程知识普及
CUDA C最佳实践-CUDA Best Practices(二)
9. 内存优化 看页数也知道,内存优化是性能提升最重要的途径。目标在于通过最大化带宽获得对硬件的最大使用率。最好使用快速内存而减少慢速内存的访问。这章就是各种讨论内存优化。 9.1. 主机和设备之间的
用户1148523
2018/01/09
2.2K0
CUDA C最佳实践-CUDA Best Practices(二)
GPU编程2--CUDA核函数和线程配置
  在GPU上执行的函数称为CUDA核函数(Kernel Function),核函数会被GPU上多个线程执行,我们可以在核函数中获取当前线程的ID。
猫叔Rex
2020/07/06
3.5K0
GPU编程2--CUDA核函数和线程配置
CUDA Study Notes
SSE(Streaming SIMD Extensions,单指令多数据流扩展)指令集是Intel在Pentium III处理器中率先推出的。其中包含70条指令。
恋喵大鲤鱼
2018/08/03
8580
CUDA Study Notes
【AI系统】GPU 架构与 CUDA 关系
本文会讲解英伟达 GPU 硬件的基础概念,其次会讲解 CUDA(Compute Unified Device Architecture)并行计算平台和编程模型,详细讲解 CUDA 线程层次结构,最后将讲解 GPU 的算力是如何计算的,这将有助于计算大模型的算力峰值和算力利用率。
用户11307734
2024/11/27
4110
CUDA C/C++总结
需要提下学习CUDA的目的,就是为了加速自己的应用,相比于CPU-only的应用程序,可以用GPU实现较大加速,当然程序首先是计算密集型而非IO密集型
零式的天空
2022/03/08
6840
相关推荐
cuda教程[新手入门学编程]
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档