英伟达的GPU(3)

  上节内容:英伟达的GPU(2) (qq.com)

      书接上文,上文我们讲到CUDA编程体系和硬件的关系,也留了一个小问题CUDA core以外的矩阵计算能力是咋提供的

      本节介绍一下Tensor Core 

      上节我们介绍了CUDA core,或者一般NPU,CPU执行矩阵运算的逻辑,基本就是矩阵的一条横向量*另一个矩阵的列向量(逻辑上可以这么认为)

     

    如上面的图所示,左边代表了Pascal架构就是P架构的时候 CUDA core 来处理矩阵运算的逻辑,蓝色的矩阵和紫色的矩阵分别代表两个矩阵,然后他俩做点积的时候,基本就是一个横向量*一个列向量。

      我们把这个过程细化一下:

      两个矩阵A和B,他俩点乘等于一个C,写出来其实就是这样的

      

图片

       I和J代表行和列的角标,k就是算到第几轮计算了。

       这个好理解吧。

      虽然宏观上我们说是向量点乘向量,但是微观上,其实还是一个格子对一个格子的算。

     

CUDA Core 实现矩阵乘法

  1. 矩阵分块:将大矩阵划分成适合 CUDA 核心处理的小块(block)。通常每个 block 是一个二维块,其中包含多个线程(thread)。例如,16x16 或 32x32 的 block 大小是常见的选择。

  2. 线程分配:每个线程块中的线程负责计算结果矩阵 C 中一个小块的元素。例如,一个 16x16 的 block 会有 256 个线程,每个线程计算 C 中一个 16x16 小块中的一个元素。

  3. 并行计算:每个线程独立执行矩阵乘法的部分计算。具体来说,每个线程计算一个元素Cij,它需要遍历矩阵 A 的第 i 行和矩阵 B 的第 j 列,进行乘法和累加操作。

  4. 共享内存:为了提高性能,CUDA 核心利用共享内存。共享内存是一种高速缓存,允许同一个 block 内的线程共享数据。(这我后面讲Cache和显存那块会细讲)矩阵的分块计算过程中,子矩阵会被加载到共享内存中,减少全局内存访问次数,提高计算效率。

具体计算步骤

用代码表示:

  1. 分配线程和块:

    • 定义网格(grid)和块(block)的尺寸。(这块看不懂的,去看我上一节讲的CUDA编程线程分级体系)

    • 将计算任务分配给每个块和线程。

  2. 加载数据到共享内存:

    • 每个线程块加载一小块矩阵 A 和 B 到共享内存中。

    • 这些小块矩阵被多次重复使用,减少对全局内存的访问。

  3. 计算并累加结果:

    • 每个线程计算其负责的结果矩阵 C 中一个元素。

    • 进行多次小块矩阵乘法的累加,直到完成整个矩阵乘法运算。

  4. 写回结果:

    • 计算完成后,将结果写回全局内存中的结果矩阵 C。

图片

     

     上面对比图右边那个操作就是Tensor Core的矩阵计算操作,先不解释,就光看就比左边猛很多,对吧?它就不是行列级别了,就是直接矩阵和矩阵运算了,其实当时V系列第一次出Tensor core的时候是很让人惊艳的,但是到了现在,大多数NPU都支持MXM(matrix 乘模块),但是当年V系列推出的时候还是很惊艳的,现在其实也很猛,但是主要是连年的性能提高。

    Tensor Core除了对比图中展示的,直接矩阵*矩阵,在一个单位的时钟里面能提供尽可能多的计算能力以外,还有就是可以支持16和32的混合精度能力

图片

      如上图所示,在V100刚出的时候就推出了这个功能。

      每个 Tensor Core 一个计算周期能执行 4x4x4 GEMM,就相当于64 个 FMA。

     比如对于运算D=A*B+C,其中A、B、C 和 D 是 4×4矩阵。矩阵乘法输入 A 和 B 是 FP16矩阵,而累加矩阵 C 和 D我就不非得要求是 FP16,我是FP16还是FP32 矩阵都行。

     这个对于CUDA Core来讲,也不是做不到的,你可以手动实现可以通过 CUDA 代码手动实现混合精度计算,例如使用 FP16 数据类型进行部分计算,然后转换为 FP32 进行累加等。但是这么做,第一是墨迹,多出一步增加复杂度和延迟,第二是没专门硬件给你优化啊,因为CUDA Core我们第一章讲过,固定的精度,多少就是多少。

      所以对于混合精度,现在也是LLM训练必备的能力了,从某种意义上讲,在NV上想支持,Tensor Core就是必须的了。

     

图片

    再就是A100和后面的型号的sparse matrix的压缩

    

图片

    说白了就是 稀疏矩阵,NV的Tensor core给你做的话,能把0给压没了,你矩阵变小了,算的不就快了吗,这也是为什么大家看NV的datasheet总看不懂的原因

图片

      比如上图,看着这么猛,实际上都是按稀疏矩阵算的,所以我们正常算的时候都按1半算,这也就是大家一聊H100就说900多的原因。

      Tensor Core是怎么处理矩阵计算的呢?

Tensor Core 矩阵乘法运算

    还是假设有两个矩阵 A 和 B,它们的乘积是矩阵 C。Tensor Core 的主要特点是支持 WMMA(Warp Matrix Multiply-Accumulate)操作,这是一个特定的 CUDA 函数,用于执行矩阵乘法和累加。

Tensor Core 计算步骤

  1. 分配线程和块:

    • 使用 Warp(通常是 32 个线程)来分配计算任务。

    • 一个 Warp 负责计算结果矩阵 C 的一个 16x16 子矩阵。

  2. 加载数据到共享内存:

    • 将矩阵 A 和 B 的子矩阵块加载到共享内存中。

    • 这些子矩阵块在共享内存中进行矩阵乘法运算。

  3. 执行矩阵乘法和累加操作:

    • 使用 WMMA API 来执行矩阵乘法和累加操作。

    • Tensor Core 在一个时钟周期内执行多个浮点运算。

  4. 写回结果:

    • 计算完成后,将结果写回全局内存中的结果矩阵 C。

   

这里就得提一嘴WMMA了

WMMA(Warp Matrix Multiply-Accumulate)是 NVIDIA 为 Tensor Core 提供的专用 API,用于在 CUDA 中执行高效的矩阵乘法和累加操作。WMMA API 主要特点和工作原理如下:

WMMA API 的主要特点

  1. 高效的矩阵运算:

    • WMMA API 专门优化了矩阵乘法和累加操作,能够在一个时钟周期内执行多个浮点运算,从而显著提高性能。

    • 利用 Tensor Core 的硬件支持,实现高吞吐量的计算。

  2. 支持混合精度计算:

    • WMMA API 支持混合精度计算,即输入矩阵可以使用半精度浮点数(FP16),而计算和输出可以使用单精度浮点数(FP32)。

    • 这种方式不仅提高了计算速度,还在一定程度上保持了计算精度。

  3. Warp级别的操作:

    • WMMA API 在 Warp 级别(通常是 32 个线程)进行操作。每个 Warp 负责计算结果矩阵中的一个 16x16 子矩阵。

    • 通过并行执行多个 Warp,实现大规模并行计算。

  4. 片段操作:

    • WMMA API 引入了片段(fragment)的概念,用于存储子矩阵和累加器。

    • 片段在寄存器中进行存储和操作,减少了对全局内存的访问,从而提高了性能。

WMMA API 的工作流程

  1. 声明和初始化片段:

    • 使用 wmma::fragment 声明用于存储矩阵块和累加器的片段。

    • 使用 fill_fragment 对累加器片段进行初始化。

  2. 加载矩阵数据到片段:

    • 使用 load_matrix_sync 将全局内存中的矩阵数据加载到片段中。

    • 这些数据将被加载到共享内存或寄存器中,以便快速访问和计算。

  3. 执行矩阵乘法和累加操作:

    • 使用 mma_sync 执行矩阵乘法和累加操作。

    • 该函数将两个输入矩阵片段相乘,并将结果累加到累加器片段中。

  4. 存储结果到全局内存:

    • 使用 store_matrix_sync 将计算结果从累加器片段存储回全局内存。

    • 结果矩阵的子块被写回到指定的内存位置。

    代码样例:

图片

      最后值得一说的就是CUDA core 和Tensor Core支持的精度不一样,不是啥下游任务两个都可以做,还是得看具体支持。

  

图片

     本节完,下一章写缓存结构

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/16471.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

pyqt QMainWindow菜单栏

pyqt QMainWindow菜单栏 pyqt QMainWindow菜单栏效果代码 pyqt QMainWindow菜单栏 QMainWindow 是 PyQt中的一个核心类,它提供了一个主应用程序窗口,通常包含菜单栏、工具栏、状态栏、中心窗口(通常是一个 QWidget 或其子类)等。…

【数据结构/C语言】深入理解 双向链表

💓 博客主页:倔强的石头的CSDN主页 📝Gitee主页:倔强的石头的gitee主页 ⏩ 文章专栏:数据结构与算法 在阅读本篇文章之前,您可能需要用到这篇关于单链表详细介绍的文章 【数据结构/C语言】深入理解 单链表…

[vue error] vue3中使用同名简写报错 ‘v-bind‘ directives require an attribute value

错误详情 错误信息 ‘v-bind’ directives require an attribute value.eslintvue/valid-v-bind 错误原因 默认情况下,ESLint 将同名缩写视为错误。此外,Volar 扩展可能需要更新以支持 Vue 3.4 中的新语法。 解决方案 更新 Volar 扩展 安装或更新 …

java人口老龄化社区服务与管理平台源码(springboot+vue+mysql)

风定落花生,歌声逐流水,大家好我是风歌,混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的人口老龄化社区服务与管理平台。项目源码以及部署相关请联系风歌,文末附上联系信息 。 项目简介: 人口老龄化…

Elasticsearch的Index sorting 索引预排序会导致索引数据的移动吗?

索引预排序可以确保索引数据按照指定字段的指定顺序进行存储,这样在查询的时候,如果固定使用这个字段进行排序就可以加快查询效率。 我们知道数据写入的过程中,如果需要确保数据有序,可能需要在原数据的基础上插入新的数据&#…

vue实现页面渲染时候执行某需求

1. 前言 在之前的项目中,需要实现一个监控token是否过期从而动态刷新token的功能,然而在登录成功后创建的监控器会在浏览器刷新点击或者是通过导航栏输入网址时销毁... 2. 试错 前前后后始过很多方法,在这里就记录一下也许也能为各位读者排…

【每日力扣】84. 柱状图中最大的矩形 与 295. 数据流的中位数

🔥 个人主页: 黑洞晓威 😀你不必等到非常厉害,才敢开始,你需要开始,才会变的非常厉害 84. 柱状图中最大的矩形 给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为…

redis6.2.7 搭建一主多从

1、集群规划 节点端口角色192.168.137.1026379master192.168.137.1026380slave192.168.137.1036381slave 2、伪集群搭建 2.1 创建fake_cluster 目录存放 公共配置文件 # 进入redis目录 cd /app/apps/redis-6.2.7# 创建存放伪集群的目录 mkdir fake_cluster#复制redis.conf到…

DTC 2024回顾丨云和恩墨重塑数据库内核技术,革新企业降本增效之道

在数字化浪潮席卷全球的当下,关系型数据库作为市场主导力量的地位依然稳固。然而,面对新兴数据库与服务形态的挑战,以及企业日益强烈的降本增效需求,数据库技术的发展必须紧跟时代步伐,充分发挥资源效能以提升企业竞争…

【机器学习300问】99、多通道卷积神经网络在卷积操作时有哪些注意事项?

一、多通道卷积神经网络示例 还是以图像处理为例,如果你的目标不仅是分析灰度图像特性,还打算捕捉RGB彩色图像的特征。如下图,当面对一张66像素的彩色图像时,提及的“3”实际上是指红、绿、蓝三种颜色通道,形象地说&am…

书生·浦语第二期-笔记2

课程链接:https://github.com/InternLM/Tutorial/tree/camp2 视频地址:轻松玩转书生浦语大模型趣味Demo_哔哩哔哩_bilibili 大模型及InternLM介绍 大模型:人工智能领域中参数数量巨大、拥有庞大计算能力和参数规模的模型 特点&#xff1a…

【Linux杂货铺】进程通信

目录 🌈 前言🌈 📁 通信概念 📁 通信发展阶段 📁 通信方式 📁 管道(匿名管道) 📂 接口 ​编辑📂 使用fork来共享通道 📂 管道读写规则 &…

初中英语优秀作文分析-002Who stole the cupcake-谁偷了纸杯蛋糕?

更多资源请关注纽扣编程微信公众号 记忆树 1 One Sunday afternoon, Leslie was at home with her kids, 3-year-old Angel, 6-year-old Carl, and 7-year-old Tony. 翻译 一个周日的下午,Leslie和她的孩子们在家,他们是3岁的Angel,6岁的…

镜子摆放忌讳多

镜子是我们日常生活中不可或缺的物品。在风水中,镜子的作用非常多,能够起到一定的作用。镜子的摆放位置也是非常有讲究的,摆放不好会直接影响到家人的事业、财运、婚姻乃至健康等诸多方面。 第一个风水忌讳,镜子对大门。大门的正前…

Linux防火墙之iptables(二)

一.SNAT策略概述 1.SNAT 策略的典型应用环境 局域网主机共享单个公网IP地址接入Internet(私有IP不能在Internet中正常路由) 局域共享上网 2.SNAT 策略的原理 源地址转换,Source Network Address Translation 修改数据包的源地址 未作SNAT转换…

用three.js+echarts给公司写了一个站点数据大屏系统经验总结

时间过的好快,参加公司的新项目研发快一年了,五一机器人项目首秀,我们遇到了高并发集中下单情景,然后海量数据处理场景来了,给我在后端领域的高并发实践业务上画上了漂亮的一笔经验。人都是在磨练中成长,我很感谢这次给我的机会,虽然有点累,但也有点小成就。正好现在有…

AGI系列(1):掌握AI大模型提示词优化术,提问准确率飙升秘籍

当我们向AI大模型提问时,通常人们的做法是有什么问题,就直接去问,得到大模型的回复结果,时好时坏,完全没有可控性。 那么有没有一种方式或是一套方法,可以让我们向大模型提问时,得到的结果更准确…

nacos 2.3.3 Windows系统安装详细版

1,下载 https://github.com/alibaba/nacos/releases 2,解压 3,将nacos的内置库(derby),修改为我们自己的 mysql 3.1 创建一个数据库 3.2 连接数据库 3.3 执行mysql 脚本,在nacos的conf 目录下 mysql-schema.sql 执…

深入了解 Golang 多架构编译:交叉编译最佳实践

随着软件开发领域的不断发展,我们面临着越来越多的挑战,其中之一是如何在不同的平台和架构上部署我们的应用程序。Golang(Go)作为一种现代化的编程语言,具有出色的跨平台支持,通过其强大的多架构编译功能&a…