当前位置: 首页 > news >正文

揭秘Tensor Core黑科技:如何让AI计算速度飞跃

  dbb7de9af4ef26b8a2cd9795e430c3be.jpeg

揭秘 Tensor Core 底层:如何让AI计算速度飞跃


Tensor Core,加速深度学习计算的利器,专用于高效执行深度神经网络中的矩阵乘法和卷积运算,提升计算效率。

Tensor Core凭借混合精度计算与张量核心操作,大幅加速深度学习模型的训练和推理。它采用半精度(FP16)作为输入输出,全精度(FP32)存储中间结果,确保精度同时最大化效率。这种高效计算方式,使Tensor Core能在短时间内完成大量矩阵运算,为深度学习带来质的飞跃。

Tensor Core 显著超越传统CUDA Core,每个时钟周期可执行高达4x4x4的GEMM运算,即同步完成64次浮点乘法累加(FMA),实现前所未有的计算效率。

Tensor Core的并行计算大幅加速深度学习模型的训练与推理,显著提升计算效率,引领人工智能领域迈向革命性新篇章。

TensorCore 计算原理

下面我们首先来回顾一下 Tensor Core 的计算原理。

fa0b8a3f179936adcba77b97628a718a.jpeg

Tensor Core 计算

深绿色4x4矩阵A与紫色4x4矩阵B相乘,再与绿色矩阵C相加。混合精度技术在此应用中大放异彩,计算时采用FP16提高速度,而存储时则灵活选择FP32或FP16以保持数据精度,实现高效与准确性的完美融合。

数学计算中,D矩阵的元素由矩阵A的一行与矩阵B的一列相乘,再与矩阵C的对应元素相加得出,公式精准呈现这一计算过程。

2753e32bd9af407f7ca3a569ae12d8a7.jpeg

NVIDIA的GPU Tensor Core通过矩阵计算而非逐行处理,大幅提升计算效率。其计算模拟图展示了其高效能力,展现了其专业性和创新力。

c05f231d792ec742fa07ac3116d112c2.jpeg

Tensor Core FMA

Pascal架构(无Tensor Core)如图左,每时钟周期以元素乘行的方式,4次相乘得一列数据。而Volta架构(含Tensor Core)如图右,其Tensor Core直接计算矩阵A与B的乘积,一次性输出完整矩阵。Volta的高效性在矩阵运算中尤为显著,展现了显著的性能优势。

Volta V100 GPU相较于Pascal P100,在AI吞吐量上实现了飞跃,每个SM的AI吞吐量激增8倍。更值得一提的是,Volta架构在SM数量和核心设计上的精妙优化,使得整体性能飙升,总提升高达12倍。

TensorCore 指令流水

指令流水技术显著提升处理器效率,它将指令分解为多个精细步骤,各由专用电路并行处理。这种流水线式的连续执行方式,实现了指令的高效并行处理,极大提升了执行效率。

0a46219190dbf9c7e1e4c3932393182c.jpeg

Tensor Core 模拟电路

Tensor Core模拟电路图展示了矩阵计算的核心操作。加号代表矩阵加,乘号则代表矩阵乘,这两者是矩阵计算的基础。图中绿色长方块为寄存器,其中16位横置寄存器用于存储输入与中间数据,而32位竖向寄存器则用于累积结果或高精度数据存储,确保计算高效精确。

在Tensor Core中实现矩阵相乘,即A行乘B列(假设长度均为4),其电路示意图详细展示了计算过程。无需考虑矩阵切分,我们聚焦于这一核心运算的精准实现。

Tensor Core 计算中,输入为16bit数据,乘加后需32位寄存器存储中间数据。高精度存储寄存器紧邻实际计算单元,实现A矩阵行与B矩阵列的乘法操作,简洁高效,确保计算精确性。这一设计优化了矩阵运算的效率和准确性。

GPU V100中,计算核心为矩阵间直接相乘生成新矩阵。模拟电路演示仅展示其中行列间FMA运算,生成单一元素的过程,凸显GPU强大计算能力。

那么一个矩阵中更多元素的是如何进行计算的呢?

007deaae7b51bed39c7d78b6b4c0961b.jpeg

Tensor Core 矩阵模拟电路

矩阵A的行与矩阵B的列通过FMA运算生成一个元素,如首个蓝色方块所示。整体计算过程犹如电路拼接,简单地将A矩阵的每一行与B矩阵的每一列相乘,从而构建出整个矩阵的每个元素。

在此时,A、B矩阵的寄存器应各自构成一组阵列,实现并行读取与计算。这种阵列布局使矩阵的每个元素都能执行FMA计算,显著提升计算效率。

下面我们再来了解下指令流水的 Pipline 是如何组织起来的。

当我们进行一个 Fp32 标量元素乘加操作的指令时,就像下面图所示。

b4165593cdc1978d428286d3ace8b85a.jpeg

Tensor Core 标量流水线

Tensor Core内乘法运算仅支持Fp16,而存储与加法运算则采用Fp32,巧妙地实现了乘法运算的精简,显著提升计算效率。

c2e0f6e84f5c7fda5297b3e012122519.jpeg

Tensor Core 两个元素流水线

Tensor Core计算时,输出单个元素需A的一行与B的一列相乘,高效实现依赖四条并行Pipeline流水线,确保高效能处理。

279331e162345e6d860490fb810527f8.jpeg

Tensor Core 一行 x 一列流水线

图示中,绿色指令流水与黄色流水线共同完成了部分计算。为全面计算所有元素,需高效拼接大量指令流水,确保计算流畅无阻。

eb7d7a819b4bce8c29e6ca72227d4c3b.jpeg

Tensor Core 矩阵流水线

数据在流水线中的读写遵循明确规律:乘法计算时,从存储单元读取两数据;计算完成后,Round阶段将结果写回单元。在特定时刻,流水线涉及四个数据:两个用于计算,两个存储回寄存器。这一流程确保了数据的高效处理与准确存储。

Tensor Core的高效运算得益于精心设计的指令流水线处理。这种设计使数据读取、计算和写入无缝交替,最大化硬件资源利用率,显著提升计算效率。流水线技术不仅加速Tensor Core运算,更为深度学习应用提供强大动力,实现快速、高效的计算体验。

TensorCore 线程执行

在整体 CUDA 软件设计方面,其目的是与 GPU 计算和存储分层结构相匹配。

NVIDIA CUDA定义Tensor Core为通用编程(General Programming)范式,旨在通过CUDA平台最大化Tensor Core的硬件效能。CUDA让开发者能够运用通用编程模型,精准调用Tensor Core功能,实现并行计算的高效运行,从而显著提升计算效率。

Tensor Core 的计算简化为 C = A * B,但面对大矩阵时,由于 Tensor Core 仅支持4x4的运算,需将矩阵切片并分配到 Thread Block 中。这种分片处理策略确保了大规模矩阵运算的高效执行,充分发挥了 Tensor Core 的计算能力。

fc662a0b184408c3a95f0282928aca6c.jpeg

在软件层面,我们定义Warp以分配切片矩阵至不同线程束。通过线程并行执行,实现矩阵乘法的高效计算,充分利用Tensor Core的计算潜能。此分块、分配与并行化策略有效释放硬件资源,极大提升计算效率,为深度学习及科学计算等应用带来显著加速效果。

下面我们将详细展开 Tensor Core 是如何完成大的矩阵计算的。

Block-level 矩阵乘

Tensor Core中,GEMM(矩阵乘)每次仅处理小矩阵块。实际操作时,需将矩阵A、B分别切分为小块,以计算出小矩阵C。此过程高效且精准,如图所示。

3f72ef0413c1ab89ec00aad33e217581.jpeg

Block-level 的矩阵乘

for&nbsp;(int&nbsp;mb&nbsp;=&nbsp;O;&nbsp;mb&nbsp;<&nbsp;M;&nbsp;mb&nbsp;+=&nbsp;Mtile)
&nbsp;&nbsp;for&nbsp;(int&nbsp;nb&nbsp;=&nbsp;O;&nbsp;nb&nbsp;<&nbsp;N;&nbsp;nb&nbsp;+=&nbsp;NtiLe)
&nbsp;&nbsp;&nbsp;&nbsp;for(int&nbsp;kb&nbsp;=&nbsp;O;&nbsp;kb&nbsp;<&nbsp;K;&nbsp;kb&nbsp;+=&nbsp;Ktile)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//compute&nbsp;Mtile-by-Ntile-by-Ktile&nbsp;matrix&nbsp;product
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(int&nbsp;k&nbsp;=&nbsp;O;&nbsp;k&nbsp;<&nbsp;Ktile;&nbsp;++k)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(int&nbsp;i=&nbsp;O;&nbsp;i<&nbsp;Mtile;&nbsp;++i)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(int&nbsp;j=&nbsp;O;&nbsp;j<&nbsp;Ntile;++j)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;row&nbsp;=&nbsp;mb&nbsp;+&nbsp;i;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;col&nbsp;=&nbsp;nb&nbsp;+&nbsp;j;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;C[row][col]&nbsp;+=,A[row][kb&nbsp;+&nbsp;k]&nbsp;*&nbsp;B[kb&nbsp;+&nbsp;k][col];
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;}

如代码所示,我们沿维度将循环嵌套划分为块,进而分解为Mtile-by-Ntile的独立矩阵乘。最终,通过累加Mtile-by-Ntile-by-Ktile的矩阵乘积,高效计算每个乘积,确保性能与效率的双赢。

在GPU计算中,CUDA kernel grid将线程块精准映射至输出矩阵D的各分区,实现高效的并行计算。线程块并行执行Mtile-by-Ntile-by-Ktile矩阵乘法,并在K维上迭代,累积计算结果。这种基于Thread Block的并行策略,确保了计算资源的高效利用,显著提升了矩阵乘法的性能。

Warp-level 矩阵乘

e25a8878fe3a38ce270dc70784087b2c.jpeg

Warp-level 的矩阵乘

CUDA编程模型中,矩阵乘法操作在线程块内执行,实则由Warp单元分配执行。Warp作为GPU的执行单元,由32个线程协同工作,共同执行指令,显著提升矩阵乘法的执行效率。

矩阵乘法中,为提升计算速度和降低内存访问延迟,我们常将矩阵A、B的部分数据载入共享内存(SMEM)。SMEM是线程块内共享的快速内存,支持线程间数据交换和协作,减少了对全局内存的频繁读取,显著提升了计算效率。

在矩阵乘法中,Warp负责高效计算结果矩阵C的部分或全部。通过将C的不同块分配给不同的Warp,实现并行处理。Warp内的线程同步执行,协同工作,共享内存数据以完成计算任务,确保计算效率与准确性并存。

矩阵乘法中,Warp内线程协同操作,通过共享内存(SMEM)加载数据至寄存器(RF)进行乘加运算,结果再存入寄存器或全局内存,高效完成一系列计算任务。

b1c20a424050543579c8c97df1ccf64c.jpeg

Warp-level 的矩阵乘展开

下面我们详细解释一下这个过程:

Warp由多线程组成,协同工作以高效处理矩阵乘法。线程间紧密合作,通过精准乘加运算,迅速得出准确结果,大幅提升计算效率。

Warp线程在计算时,需从共享内存迅速加载矩阵A、B的片段至寄存器,确保数据快速访问与计算。加载速度需足够快,避免线程等待,维持计算高效性。这一优化确保计算流程的高效流畅,为数据处理提供强大支持。

随后,各线程在寄存器上并行执行矩阵乘法,计算矩阵C的元素,暂存于寄存器中直至所有乘加操作完成。计算中,我们对共享内存数据实施K维排序,旨在优化线程的数据访问效率,显著减少内存访问延迟,确保线程高效获取所需数据,从而最大化计算效率。

Thread-level 矩阵乘

Tensor Core 高效并行执行核心操作:矩阵A乘以矩阵B,直接得出C矩阵,展现计算的高效与简洁。

Tensor Core作为NVIDIA GPU的核心硬件,通过CUDA编程模型的WMMA(Warp级矩阵乘加)API得到完美支持。该API专为Tensor Core设计,让开发者在CUDA程序中直接解锁硬件加速潜力。利用WMMA API,开发者不仅能高效执行矩阵乘法累积操作,还能轻松管理数据加载、存储及同步,实现性能与效率的双重飞跃。

在GEMM软硬件分层中,数据复用至关重要。面对庞大矩阵数据,高效复用能显著提升计算效率。通过全局内存、共享内存和寄存器等不同内存层次结构,我们精心管理和复用数据,确保每一层都能充分发挥数据价值,实现高效计算。

31d38573f05a9a17f803252680199a2e.jpeg

Thread-level 的矩阵乘

大矩阵高效计算的核心在于将其分割并存储于全局内存。计算时,小块数据被迅速加载至共享内存或寄存器,大幅减少内存访问延迟,提升计算效率。完成每块矩阵乘法后,结果即刻累积,涉及中间结果从寄存器或共享内存回流至全局内存,并适时同步与累加,确保最终矩阵乘法结果的完整性。这一流程,确保计算速度与精度的双重优化。

通过精心设计的计算和数据管理操作,我们高效完成了GEMM计算任务,并将结果精准地写回输出矩阵C。此过程充分利用了Tensor Core的硬件加速和CUDA编程模型的灵活性,显著提升了矩阵乘法的计算效率。

累积矩阵结果

118d8f291012ea1d456787399c1eb6b3.jpeg

Tensor Core 累积矩阵并写出最终结果

Tensor Core中的WMMA API支持register file中临时结果的快速回传。特别地,store matrix sync API能将数据高效搬移至共享内存(SMEM),确保数据处理的流畅与高效。这一机制显著提升了计算效率,为深度学习等应用提供了强大支持。

SMEM内高效累积数据,存储至全局内存。通过全局内存,实现数据块的无缝拼接,快速回传并输出结果,确保高效处理。

整体计算过程

下面我们来总结一下整个的计算过程:

ceb5ab4b03abaaf3aa8d76767eee4177.jpeg

Tensor Core 计算全流程

矩阵进行GEMM计算前会先分块,并存储在GPU的全局内存中,这是GPU上最大的内存区域,专为处理计算中需频繁访问的海量数据而设计,确保高效的数据处理速度。

计算前,程序将矩阵分块加载至共享内存,确保低延迟访问。共享内存是线程块内所有线程可访问的数据池,实现数据的高效共享与重用,优化计算性能。

在矩阵乘法运算中,线程高效地将共享内存数据加载至其私有寄存器,这是GPU上速度最快的内存空间。每个线程拥有独立寄存器文件,确保运算的独立性。在Tensor Core中,数据直接存储于其寄存器文件,并进行高速计算,极大提升了矩阵乘法的执行效率。

计算完成后,结果直接写回共享内存,而非滞留于Tensor Core寄存器。此举旨在优化中间结果存储与线程间数据交互。CUDA的WMMA API提供了如store matrix sync等函数,确保数据同步累积准确无误,从而高效利用共享内存资源,提升数据处理效率。

在共享内存中累积结果后,将自动写回全局内存。此过程需多线程块协同,因矩阵乘法需多线程块合力完成。全局内存确保各线程块结果无缝拼接,形成完整的矩阵乘法结果,高效且精准。

总结

深度学习中的GEMM计算涵盖矩阵分块、数据加载至共享内存与寄存器、Tensor Core内计算、结果存回共享内存并写入全局内存,实现高效数据处理。

Tensor Core,精通数学的计算专家,擅长深度学习的矩阵乘法和卷积运算。其采用FP16计算,FP32存储中间结果,确保高效且精确。Tensor Core能一次性处理4x4矩阵乘法,相较于CUDA Core,计算速度显著提升,为深度学习领域带来革命性变革。

借助WMMA API与CUDA编程技术,我们高效利用GPU资源,实现矩阵乘法运算性能飞跃,轻松应对高性能计算需求。


-对此,您有什么看法见解?-

-欢迎在评论区留言探讨和分享。-

相关文章:

  • mysql8忘记密码重置密码和创建新用户
  • Golang协程和通道
  • 数据结构的希尔排序(c语言版)
  • MySQL 高级 - 第十章 | 性能分析工具的使用
  • springcloud-服务拆分与远程调用
  • 所以研究生有不变胖的吗?
  • 【考研数据结构知识点详解及整理——C语言描述】第一章算法和算法评价
  • 3步骤找回丢失文件!EasyRecovery让你轻松应对数据灾难!
  • C++的第一道门坎:类与对象(二)
  • NoSQL数据库技术与应用 教学设计
  • 代码随想录算法训练营第二十一天 | 530.二叉搜索树的最小绝对差、501.二叉搜索树中的众数、236. 二叉树的最近公共祖先
  • NLP技术发展和相关书籍分享
  • MTK Android9.0 给vendor下文件夹权限,用于读取文件列表
  • 成都蓝蛙科技引领AIGC创新,亮相中国AIGC开发者大会
  • Java研学-RBAC权限控制(七)
  • 002-读书笔记-JavaScript高级程序设计 在HTML中使用JavaScript
  • Android单元测试 - 几个重要问题
  • docker-consul
  • Hexo+码云+git快速搭建免费的静态Blog
  • JavaScript HTML DOM
  • js数组之filter
  • laravel with 查询列表限制条数
  • LeetCode18.四数之和 JavaScript
  • node学习系列之简单文件上传
  • React 快速上手 - 07 前端路由 react-router
  • Redis在Web项目中的应用与实践
  • 关于Flux,Vuex,Redux的思考
  • 利用DataURL技术在网页上显示图片
  • 免费小说阅读小程序
  • 线上 python http server profile 实践
  • 线性表及其算法(java实现)
  • 正则与JS中的正则
  • MPAndroidChart 教程:Y轴 YAxis
  • Spark2.4.0源码分析之WorldCount 默认shuffling并行度为200(九) ...
  • 哈罗单车融资几十亿元,蚂蚁金服与春华资本加持 ...
  • 曜石科技宣布获得千万级天使轮投资,全方面布局电竞产业链 ...
  • # 透过事物看本质的能力怎么培养?
  • #### go map 底层结构 ####
  • #我与Java虚拟机的故事#连载06:收获颇多的经典之作
  • $$$$GB2312-80区位编码表$$$$
  • (翻译)Quartz官方教程——第一课:Quartz入门
  • (过滤器)Filter和(监听器)listener
  • (三)elasticsearch 源码之启动流程分析
  • (算法)Game
  • (已解决)报错:Could not load the Qt platform plugin “xcb“
  • (原创)可支持最大高度的NestedScrollView
  • (转)scrum常见工具列表
  • (转)可以带来幸福的一本书
  • (转载)Linux网络编程入门
  • (转载)在C#用WM_COPYDATA消息来实现两个进程之间传递数据
  • ***监测系统的构建(chkrootkit )
  • ./indexer: error while loading shared libraries: libmysqlclient.so.18: cannot open shared object fil
  • .htaccess 强制https 单独排除某个目录
  • .net core 6 使用注解自动注入实例,无需构造注入 autowrite4net
  • .net web项目 调用webService