本讲座:基准测试/分析 + 编写内核

总结

编程模型(PyTorch、Triton、PTX)与硬件之间的差距 => 性能奥秘
理解扩展的基准测试
用于理解 PyTorch 函数内部结构的分析(用内核触底)
看 PTX 汇编,了解 CUDA 内核的内部结构
编写函数的 5 种方法:manual、PyTorch、编译、CUDA、Triton
GeLU(按元素)、softmax(按行)、matmul(复聚合)
关键原则:组织计算以尽量减少读/写
关键思想:内核融合(仓库/工厂类比)、平铺(共享内存)
自动编译器(Triton、torch.compile)会随着时间的推移而变得更好

硬件

![[Pasted image 20250815095146.png]]

计算:流式多处理器 (SM) [A100:108]
内存:
DRAM [A100: 80GB] - 大而慢
二级缓存 [A100: 40MB]
L1 缓存 [A100:每 SM 192KB] - 小、快

执行模型

![[Pasted image 20250815095139.png]]

线程:进程单个索引(即 f(i))
线程块:(又名并发线程数组):在单个 SM 上调度
网格 :线块的集合

为什么使用线程块?共享内存。

直观理解:将读取相似数据的 f(i)分组在一起
线程块内的线程拥有共享内存(速度与 L1 缓存相当)[A100: 164KB]
可以在块内同步线程(用于读取/写入),但不能跨块同步

硬件与执行相互作用

![[Pasted image 20250815095210.png]]

线程块以波次形式调度到 SM 上。
问题:最后一波次线程块较少,导致部分 SM 空闲(低占用率)。
波形量化:使线程块数量能被 SM 数量整除。
经验法则:线程块的数量应该 >= 4 倍的 SM 数量
挑战:执行模型中隐藏了一些硬件方面的特性(例如,调度、SM 数量)。

算术强度:每字节的浮点运算次数

如果数值较高,表示操作是计算密集型(好)
如果数值较低,表示操作是内存密集型(坏)
一般规则:矩阵乘法是计算密集型,其他操作都是内存密集型

重要提示:请测试和分析您的代码!

您可以阅读规格表(营销材料)和论文
但性能取决于您的库版本、硬件和工作负载
因此,测试和分析您的代码是必不可少的。

示例计算:在多层感知机(MLP)上运行前向/后向传播。

run_mlp(dim=128, num_layers=16, batch_size=128, num_steps=5)
benchmarking() # 用时多久?profiling() # 时间花在哪里?

每次做修改时,请务必进行基准测试/性能分析!

矩阵乘法基准测试

首先,我们来基准测试方形矩阵的矩阵乘法。

![[Pasted image 20250815100516.png]]
![[Pasted image 20250815100527.png]]

在1024和2048上,时间几乎没有增加
因为在执行时这些矩阵乘法时存在恒定因子的开销,如从CPU传送到GPU、启动内核

让我们测试一下我们的多层感知机!

![[Pasted image 20250815100744.png]]

每次MLP执行大约需要五秒钟

性能分析

虽然基准测试关注的是端到端时间,但性能分析则关注时间的具体花费位置。
很明显:性能分析可以帮助你了解时间具体花费在哪些地方。
更深入:性能分析帮助你了解(被调用的内容)。
PyTorch 有一个内置的性能分析器 https://pytorch.org/tutorials/recipes/recipes/profiler_recipe.html
让我们对一些代码进行性能分析,看看幕后发生了什么。

CUDA

CUDA 是 C/C++ 的扩展,包含管理 GPU 的 API。
我们将编写一些函数f,当调用这个CUDA内核时,它将自动对向量或矩阵的所有元素调用f,然后我们将并行计算我们想要的一切
网格:
线程块的集合:numBlocks = (2, 4),blockDim = (1, 8)

线程块:
线程的集合:blockIdx = (0, 1)

线程:
单个操作单元:threadIdx = (0, 3)。

你编写线程执行的代码,并使用 (blockIdx, blockDim, threadIdx) 来确定要执行的操作。
设置 CUDA_LAUNCH_BLOCKING,以便如果有错误,CUDA 会告诉你哪里出了问题。

os.environ["CUDA_LAUNCH_BLOCKING"] = "1"

load_inline 函数使得编写 CUDA 代码并将其绑定到 Python 模块变得方便,以便立即使用。

CUDA 代码:包含完整的逻辑

实际内核所在,这将被发送到GPU,并进行计算,然后返回结果
![[Pasted image 20250815104644.png]]

这是一个包装器,将协调内核的启动,内核实际上存在于GPU中

TORCH_CHECK(x.device().is_cuda());//确保x存在于GPU设备中
TORCH_CHECK(x.is_contiguous());//确保x是连续的,位于连续的内存块中
// Allocate empty tensor
torch::Tensor y = torch::empty_like(x);

![[Pasted image 20250815104736.png]]

总结

  1. 编程模型(如PyTorch、Triton、PTX)与硬件的“差距”为何会导致性能差异?
    不同编程模型对硬件细节的抽象程度不同:PyTorch封装了底层逻辑,易用但可能未充分利用硬件特性;Triton提供中间抽象,平衡灵活性与性能;PTX接近硬件指令,可控性最高但复杂度大。这种抽象差距导致对内存访问、线程调度等硬件细节的优化程度不同,最终体现为性能差异。

  2. GPU执行模型中,线程、线程块、网格的关系及对硬件利用率的影响是什么?
    线程是最小执行单元,负责单个索引操作;线程块是线程的集合,在单个SM上调度,共享块内共享内存;网格是线程块的集合。线程块数量需与SM数量匹配(建议≥4倍SM数),否则易因“最后一波次线程块不足”导致SM空闲,降低硬件利用率。

  3. 算术强度的定义及对GPU性能的指导意义是什么?
    算术强度指每字节数据传输对应的浮点运算次数。数值高表示计算密集型(如矩阵乘法),能充分利用GPU算力;数值低表示内存密集型(如多数逐元素操作),易受内存带宽限制。优化需针对类型调整策略:计算密集型提升并行效率,内存密集型减少数据传输。

  4. 基准测试与性能分析的核心区别及各自作用?
    基准测试关注端到端时间,用于评估整体性能(如矩阵乘法不同尺寸的耗时);性能分析聚焦时间分布,定位具体瓶颈(如哪部分内核、内存操作耗时最长)。二者结合:基准测试衡量优化效果,性能分析指导优化方向。

  5. CUDA内核编写中,线程块设计需考虑哪些硬件特性?共享内存的关键作用是什么?
    线程块设计需匹配SM资源:受限于共享内存大小(如A100每块164KB)、线程数上限,并需保证内存访问合并(匹配DRAM突发传输)。共享内存位于SM内部,速度接近L1缓存,核心作用是缓存块内重复访问的数据,减少全局内存读写,提升数据重用效率。

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

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

相关文章

Spring Boot 整合网易163邮箱发送邮件实现找回密码功能

在开发用户系统时,发送邮件是一项常见需求,例如用户忘记密码时,通过邮箱发送验证码来验证身份并重置密码。本文将结合 Spring Boot 和 163 邮箱,演示如何实现邮件发送功能。 一、前提条件 普通用户的 163 邮箱可以在 Spring Boot…

如何在mac玩windows游戏?3个工具推荐,不用换电脑!

Mac电脑虽然很流畅,但它也存在局限性,其中一点游戏玩家应该深有体会,那就是无法直接玩Windows专属游戏,只能对着琳琅满目的游戏望眼欲穿。别急,我有办法让你在mac玩windows游戏,下面就来分享我的经验。一、…

自回归(Auto-Regressive, AR),自回归图像生成过程

根据论文中“**T2I Generation via Next-Token Prediction**”一节,自回归(Auto-Regressive, AR)文本到图像(T2I)模型的图像生成过程可分为三个主要步骤,其原理和损失函数如下:---### &#x1f…

在mysql中,modify ,change ,rename to的作用是什么

在 MySQL 中,MODIFY、CHANGE 和 RENAME TO 都是 ALTER TABLE 语句的一部分,用于修改表的结构,但它们的作用和使用场景有所不同。1. MODIFY作用:用于修改表中现有列的定义,但不能修改列名。你可以使用 MODIFY 来更改列的…

【JVM】JVM的内存结构是怎样的?

JVM的内存结构是Java程序运行时内存管理的核心,不同区域有明确的职责。 一、整体划分 包括两大部分,分为线程私有区域(随线程创建/销毁,无需垃圾回收)和线程共享区域(所有线程共用,需要垃圾回收管理)。 线程私有区域:程…

青少年软件编程(python五级)等级考试试卷-客观题(2023年12月)

更多内容和历年真题请查看网站:【试卷中心 -----> 电子学会 ----> 机器人技术 ----> 五级】 网站链接 青少年软件编程历年真题模拟题实时更新 青少年软件编程(python五级)等级考试试卷-客观题(2023年12月&#xff0…

网络编程-创建TCP协议服务器

int socket(int domain, int type, int protocol);头文件&#xff1a; #include <sys/socket.h>#include <netinet/in.h> #include <netinet/ip.h>int skt_tcpfd;int domain;skt_tcpfdsocket(AF_INET,SOCK_STREAM,0);int bind(int sockfd, const struct soc…

ruoyi框架角色分配用户

分配用户&#xff0c;不要将当前正在登录的用户绑定。否则&#xff0c;在加入当前用户之后&#xff0c;取消或者添加其他用户时会被注销当前登录。

Java Stream常见函数与应用案例

1. Java Stream核心概念与基础函数 1.1 Stream API的设计哲学与核心特性 Java Stream API的设计哲学源于函数式编程范式&#xff0c;其核心特性体现在数据处理模式的转变上。与传统集合操作相比&#xff0c;Stream API采用声明式编程风格&#xff0c;支持链式调用&#xff0c;显…

【Canvas与徽章】中国制造金色玻璃光徽章

【成图】【代码】<!DOCTYPE html> <html lang"utf-8"> <meta http-equiv"Content-Type" content"text/html; charsetutf-8"/> <head><title>中国制造金色玻璃光徽章 Draft1</title><style type"tex…

终结系统裸奔:Debian老旧版本安全加固终极指南

核心警示:Debian 8与10已结束官方支持,暴露于0day漏洞风险中。本文提供的加固方案仅为迁移前的临时防护措施,非长久之计。 一、老旧Debian系统的致命隐患 支持状态: Debian 8(Jessie):2018年终止安全更新 Debian 10(Buster):2024年7月结束主流支持 风险清单: 无补…

Ape.Volo项目源码学习(1:源码下载及运行)

Ape.Volo项目是基于 .Net 8 、SqlSugar、Vue2.x、RBAC、前后端分离开箱则用的中后台快速开发框架&#xff0c;其使用Async/Await异步编程&#xff0c;支持CodeFirst模式、RabbitMQ/RedisMQ消息队列、CORS 跨域配置、数据库操作&#xff08;读写分离、多库、分表&#xff09;、支…

2-4.Python 编码基础 - 流程控制(判断语句、循环语句、break 语句与 continue 语句)

一、判断语句 1、if 语句 &#xff08;1&#xff09;基本格式 if 【判断条件】:【满足条件时执行的代码块】&#xff08;2&#xff09;演示 number 10if number > 0:print("这个数是正数")# 输出结果这个数是正数2、if - else 语句 &#xff08;1&#xff09;基本…

大模型自我进化框架SE-Agent:开启软件工程自动化新时代

一、引言&#xff1a;当大模型学会“自我进化” 在软件开发领域&#xff0c;传统模式下人类工程师面对复杂任务时&#xff0c;往往需要经历反复调试、多轮迭代才能产出高质量代码。而随着大语言模型&#xff08;LLM&#xff09;的兴起&#xff0c;一种名为**SE-Agent&#xff…

UE官方文档学习 C++ TAarry 查询(四)多种查询方式

一.IndexofByKey 返回索引通过值&#xff0c;返回来查找键。二IndexOfByPredicate通过定义二元谓词&#xff0c;来判定是否有符合谓词判定的元素。符合条件True的&#xff0c;才返回Index。这里所谓Lamda,函数就是 把函数当作参数输入&#xff0c;里面的参数值传递前加个[]。这…

根据Wireshark捕获数据包时间和长度绘制电脑发射信号波形

下一期&#xff1a; 根据Wireshark捕获数据包时间和长度绘制路由器发送给电脑数据的信号波形-CSDN博客 一、Wireshark采集数据 数据格式&#xff1a; 在我的另一篇博客中详细介绍了怎么导出数据&#xff1a; Wireshark导出数据包时间和长度-CSDN博客 通过MATLAB加载数据&a…

Suno API 接入指南:快速上手与高效集成

随着 AI 技术的发展&#xff0c;音乐生成已经逐渐成为开发者和创作者探索的新方向。Suno API 提供了一套简洁的接口&#xff0c;让我们能够通过代码快速生成音乐、歌词&#xff0c;甚至旋律。本文将带你从零开始&#xff0c;完成 Suno API 的接入与调用&#xff0c;并分享一些高…

React Hooks原理深潜:从「黑魔法」到「可观测」的蜕变之旅

文章目录【技术栈深潜计划】React Hooks原理深潜&#xff1a;从「黑魔法」到「可观测」的蜕变之旅一、引言&#xff1a;为什么我们需要“深潜”Hooks&#xff1f;二、基石&#xff1a;没有JavaScript闭包&#xff0c;就没有Hooks2.1 闭包的精简回顾2.2 Hooks与闭包的关联三、核…

MySql知识梳理之DDL语句

例子&#xff1a;为emp表增加一个新的字段”昵称”为nickname&#xff0c;类型为varchar(20)alter table emp add nickname varchar(20) comment 昵称;例子&#xff1a;将emp表的nickname字段修改为username&#xff0c;类型为varchar(30)ALTER TABLE emp CHANGE nickname us…

Games 101 第四讲 Transformation Cont(视图变换和投影变换)

三维变换 三种变换 下面分别是放缩&#xff0c;旋转&#xff0c;平移在旋转当中&#xff0c;绕着y轴旋转矩阵的顺序不一样&#xff0c;因为绕着y轴转在右手坐标系中 &#xff0c;z是第一轴&#xff0c;x是第二轴&#xff0c;而负号会加在第一轴上&#xff0c;因此负号在下面。 …