☰
GPU架构与芯片型号对应关系:从CUDA计算能力到并行编程优化
2026/10/14 1:13:37 网站建设 项目流程

1. 为什么我建议你先把“架构名”和“芯片型号”对照起来读

做 GPU 并行开发有一段时间的人,大概率都会遇到这种对话:有人在群里问“想买一张卡跑并行计算,N 卡怎么选”,底下的回答永远是“上 4090”“不如 A100”“等等,你预算多少”。如果只停留在“随便买一张高性能显卡”的层面,这个问题确实没什么可聊的。但当你真正进入 GPU 并行编程,尤其是写 CUDA、OpenCL 或 SYCL 代码并对性能有要求时,光知道“卡很猛”是不够的。你必须能从一个具体芯片型号里读出它的架构代际、计算能力、访存带宽、缓存层级、支持哪些硬件指令集,否则你会发现同一份优化代码在最贵的卡上反而跑不出该有的加速比,或者代码在 A 卡上编译通过,到另一张 A 卡上却开始疯狂走降级路径。

这一章就是专门把“架构”和“芯片型号”这张对照表讲清楚的。前面几章我们花了很多篇幅去讲 GPU 的硬件组织方式,比如 SM 里有多少个 CUDA core、shared memory 分了多少 bank、warp scheduler 是怎么发射指令的,但那都是架构层面的抽象描述。架构最终要落到物理芯片上,对应到一系列具体商品名。同一个架构可能衍生出十几种不同型号,而不同代际的架构之间,编程模型、指令特性、可用的硬件能力差异可能比想象中更大。所以这一章的作用是给你提供一张”从芯片型号反推硬件能力“的地图,读完你至少能做到:看见一张卡的型号,脑子里能快速反应出它属于哪一代架构、主流用途是什么、编程时应该注意哪些坑。

顺便说一句,这一章不会只盯着英伟达。AMD 的 RDNA 和 CDNA、英特尔的 Xe 架构,虽然市场份额各不相同,但在并行编程的世界里,它们同样有很强的存在感。尤其是这几年异构计算深入数据中心之后,你很可能被要求在非 NVIDIA 平台做移植或性能适配,提前把这些型号体系梳理清楚,能省下大量试错时间。

1.1 这一章要解决的实际问题

我先把读者按水平分一层。如果你刚接触 GPU 并行编程,你可能连“架构”和“型号”之间的关系都还没建立起来。比如你知道 RTX 4090 很贵很厉害,但你不知道它和 H100 之间到底差在哪里,更不知道同为 Ampere 架构的 A100 和 RTX 3080 在并行编程视角下竟然有完全不同的可编程特性。这种情况下,这一章是你的补课材料。

如果你已经写过半年 CUDA,你应该经常查看deviceQuery之类的工具输出,知道计算能力(Compute Capability)这个字段存在,但可能没有把它和具体的芯片型号对应起来。比如你调试过cudaGetDeviceProperties里的major、minor字段,却不清楚 8.0、8.6、8.9 这些数字背后的硬件差异是什么。这一章会把这条线索完整拉通。

如果你已经是团队里的技术负责人,那么这一章可以当作选型参考。训练大模型、做科学计算、跑实时渲染,对 GPU 硬件的要求完全不同。同样的模型,在 V100 上需要改算子,在 A100 上又不需要改,在 H100 上甚至可能要走不同的并行策略。理解型号背后的架构差异,能够帮助你更准确判断“这张卡能不能跑这个负载”。

1.2 常见认知断层:以为架构相同,型号就只是频率和显存的区别

很多初学者会有一种惯性思维:同一个架构出来的卡,无非就是核心多一些、频率高一些、显存大一些,编程视角下应该差不多。这句话对一半错一半。对的是,同一个架构确实共享同一套底层指令集和编程模型,你在编写代码时不需要为每种型号单独维护一份 CUDA 实现。错的是,不同型号之间往往不只是“量”的差异,还有“质”的差异,比如:

  • 同样是 Ampere 架构,GA100(对应 A100)和 GA102(对应 RTX 3080/3090)的Compute Capability不同,一个是 8.0,另一个是 8.6。这意味着它们对某些函数(例如异步拷贝cudaMemcpyAsync的优化路径、double 精度运算能力、__syncwarp的行为)的支持存在差异。
  • 同一代架构里,数据中心卡和游戏卡会刻意做功能切割。NVIDIA 把很多专业计算特性放在数据中心系列里,而游戏卡可能仅保留少量相关功能。
  • 显存带宽、L2 缓存大小在不同型号之间差距巨大,这直接影响访存密集型算子的优化方式。RTX 3090 虽然有 24GB 显存,但它的 L2 只有 6MB;A100 的 L2 是 40MB。对某些需要反复复用数据的 kernel,缓存大小决定了你到底是带宽瓶颈还是访存延迟瓶颈。

所以,这章要建立的第一个概念就是:架构是“代”,型号是“代里的具体 SKU”,两者之间是族谱关系,而不是等同关系。编程时你针对的是架构特性,但最终被nvcc、设备驱动、运行时库共同处理的是具体型号。

2. NVIDIA 的架构线:从 Compute Capability 反推芯片特性

NVIDIA 的架构命名有很多套系统。对游戏用户来说,他们关心的是 GeForce RTX 40 系列、30 系列;对数据中心用户来说,他们关心的是 A100、H100、V100;对嵌入式用户来说,还有 Jetson 系列。但所有这些产品,在并行编程视角下,最终会落到一个统一标识上:Compute Capability(计算能力)。它由主版本号和次版本号组成,比如 8.6、7.5、9.0。主版本号大体对应架构代际,次版本号标记同代际内部的能力差异。

我第一次认真研究这个编号系统的时候,最大的感受是:NVIDIA 并没有严格按照“每两年一个大架构”的节奏来提升主版本号。比如 Turing 是 7.5,Volta 是 7.0,它们共享主版本 7;但 Turing 和 Volta 的硬件特性差异很大。而 Ampere 这一代特别特殊,数据中心用的 GA100 是 8.0,但游戏卡用的 GA102 是 8.6,GA10B 这种笔记本芯片甚至还会有一点小差异。等到 Ada Lovelace 架构发布,直接跳到 8.9;接着 Hopper 到 9.0。

2.1 一张可对照的 NVIDIA 架构芯片表格

为了读起来方便,我整理一个简表。这里不会列全所有型号,因为那不是本章的目的;我挑的是并行编程场景里最常出现的芯片型号,以及它们在架构上的关键差异。

Compute Capability架构代际代表芯片型号关键特性常见用途
3.xKeplerK80、K20Xm早期通用计算,动态并行仍需谨慎老一代数据中心卡,基本淘汰
5.xMaxwellGTX 750 Ti、GTX 980功耗优化,整数运算弱老游戏卡
6.xPascalP100、GTX 1080 Ti首次原生支持 FP16、NVLink 雏形;统一内存改进老数据中心卡/老游戏卡
7.0VoltaV100Tensor Core 首次出现、独立线程调度、降低同步开销早期 AI 训练、科学计算
7.5TuringT4、RTX 2080 Ti光线追踪硬件,INT8 加速,改进 Tensor Core推理、图形、混合负载
8.0Ampere 数据中心A100第三代 Tensor Core、稀疏计算硬件支持、L2 带宽翻倍AI 训练与推理、科学计算
8.6Ampere 消费级RTX 3060 Ti / 3070 / 3080 / 3090强化 INT8/INT4、FP16 吞吐,不完整支持稀疏特性游戏与个人工作站
8.9Ada LovelaceRTX 4060 / 4070 / 4080 / 4090大规模 SM 重构,新 Tensor Core 引入 FP8 等游戏、内容创作、轻量训练
9.0HopperH100、H200第四代 Tensor Core、DPX 指令、NVLink 4.0大模型训练、高性能计算
10.xBlackwellB200、B100双 die 封装,更大吞吐最新一代数据中心 AI 加速

这张表是我个人在做工程对比时常用的一张简化版,真实的世界里细节更多。比如 Pascal 代的 P40、P4 是专门推理用的;Turing 代还有一个 RTX 6000/8000 工作站系列;Ada 代也有 RTX 6000 Ada。但核心规律是一致的:数据中心型号和消费级型号会在 Tensor Core 能力、NVLink、显存 ECC 等方面有明显切割。

2.2 为什么 Compute Capability 会直接影响编译参数

写 CUDA 时,最直接能感受到芯片型号存在感的时刻是编译选项。nvcc会允许你指定-arch=sm_80、sm_86、sm_90这样的 target。你选错了,编译出来的二进制可能无法在当前 GPU 上跑,或者跑起来只能用兼容性较差的路径。

举个例子:如果你针对sm_80(对应 A100)编译了一个 kernel,然后拿到一台只有sm_86(RTX 3090)的机器上运行,驱动会尝试通过二进制兼容机制把它转译成能执行的版本。这个过程在多数情况下可行,但性能大概率会打折扣,因为编译器在sm_80target 下根本不会生成针对sm_86特性的指令。反过来,如果你用sm_86编译,拿到sm_80卡上运行,直接就报invalid device function,因为sm_86使用的某些指令在纯sm_80设备上不存在。

我见过不少同事一开始偷懒,统一用-arch=sm_75编译,想着反正能兼容到很多卡,结果在 A100 上性能跑不满,连普通的矩阵乘法都打不过优化后的 PyTorch 默认实现。后来老老实实按目标卡分开编译,才把该用的硬件指令用上。具体怎么选-arch,应当结合你部署目标机上deviceQuery输出的Compute Capability来定,而不是想当然。

还有一个细节:major/minor和驱动版本有关系。较老的驱动可能不认识新架构的芯片,即使你nvcc用的新版本,运行时也会因为驱动太旧而无法加载。所以每次拿到一张新卡,第一步一定是更新驱动到目标卡对应的版本。这看起来是件小事,实际上在小团队里反复踩坑。

2.3 数据中心卡和消费级卡:同样架构下的“功能阉割”

很多人以为一张 RTX 3090 和一张 A100 都是 Ampere 架构,跑 CUDA 应该差不多。从参数上看,RTX 3090 有 10496 个 CUDA core,A100 有 6912 个,前者看起来还更多;显存容量 3090 有 24GB,A100 有 40GB/80GB,也差距不大。但实际用途和编程体验完全不同。

A100 拥有完整的双精度 FP64 吞吐,RTX 3090 的 FP64 吞吐被刻意压低到非常低的水平,做科学计算的人如果买消费级卡跑物理模拟,会很难受。A100 有 NVLink,RTX 3090 也有 NVLink 接口,3090 的 NVLink 带宽和连接方式完全不是为多卡大规模通信设计的,一般也不会拿它做集群互联。A100 的 L2 缓存更大,显存带宽更高,这直接影响 cache blocking 策略。A100 还支持 SRAM/寄存器文件里的异步内存拷贝cp.async,这套机制能让 load 操作与计算重叠;而在 GA102 的 8.6 上,cp.async的可用性和行为也有差异。

用一句话总结:同一代里,消费级卡通常更强调图形渲染和单卡性价比,数据中心卡则面向更高强度、更长时间、更稳定的大规模并行计算。如果你是学习者,用一张 4090 练手完全没问题;但你在 4090 上测出来的 kernel 行为,不代表它在 A100 或者其他加速卡上也会同样表现。

3. AMD 的架构对应芯片:RDNA、CDNA 与 GCN 的算盘

AMD 的 GPU 产品线在并行编程语境下一直被戏称为“难得有名字”,因为它的架构代号和商品名之间的关联不像 NVIDIA 那么直观。你可能听说过 Radeon RX 7900 XTX、Radeon RX 6700 XT、Instinct MI250X,但很少有人能立刻说出每个型号对应哪一代底层架构。实际上,AMD 并行计算相关的架构主要有三个家族:GCN、RDNA、CDNA。

GCN(Graphics Core Next)是 AMD 的老架构,从 2012 年左右开始,一直沿用到 Vega 时代。GCN 在编程上引入的“CU(Compute Unit)”概念非常接近 NVIDIA 的 SM,每 4 个 CU 组成一组,称为“Shader Engine”的调度结构,内部使用 wavefront(线程束)概念,通常一个 wavefront 是 64 个线程,和 NVIDIA 的 warp(32 线程)存在宽度差异。这在写 OpenCL 或 HIP 时会直接影响 workgroup 大小选择:一个 workgroup 如果太窄,可能导致 wavefront 利用率不足。

3.1 RDNA 系列:消费级游戏的直系后代

RDNA 1 代对应的是 RX 5000 系列,RDNA 2 代对应 RX 6000 系列,RDNA 3 代对应 RX 7000 系列。RDNA 从 GCN 里学了很多,但重新设计了调度器和缓存体系,在游戏性能上提升明显。对于并行编程来说,RDNA 有几个值得注意的特性:

  • wave32 和 wave64 的切换能力。GCN 固定一个 wavefront 64 lanes,RDNA 允许发射 32 lanes 的 wave,叫 wave32。这个变化意味着你在 RDNA 上写 kernel 时,workgroup 大小和占用率计算方式需要重新调整。wave32 在某些非矩阵、标量指令更多的负载下效率更高,但并不是所有代码都自动受益。
  • 访存带宽巨大但 L2 相对小。RDNA 2 的 Infinity Cache 是个面向游戏的缓存方案,对通用计算来说,它的命中率行为和 NVIDIA 的 L2 截然不同,编写 stencil 或归约类 kernel 时,不能直接用 NVIDIA 上的 cache 优化经验。

如果你只是学习并行编程,用 RDNA 消费卡写 HIP 或 SYCL 代码是可行的,但要注意 AMD 的软件栈相对没那么完善,hipDeviceProp里能够拿到的设备属性不像 CUDA 那么齐全,某些厂商提供的扩展特性文档也比较稀缺。

3.2 CDNA 系列:面向计算和数据中心的算力卡

CDNA(Compute DNA)是 AMD 专门面向数据中心的架构,跟 RDNA 的最大区别是:它不承担图形渲染职责,专注于矩阵运算、AI、HPC。对应芯片型号主要是 Instinct 系列:MI50、MI100、MI250、MI250X、MI300X 等。

CDNA 1 代对应 MI100,核心亮点是 Matrix Core,类似 NVIDIA 的 Tensor Core,专门加速 FP16 和 BF16 计算。CDNA 2 代对应 MI200 系列,把双精度 FP64 的吐量做得相当高,这使得 AMD 这些卡在分子动力学、流体力学这类需要高精度数值计算的科学计算场景里非常有竞争力。CDNA 3 代对应 MI300 系列,开始把 CPU 和 GPU 组合封装在同一个加速器里,走的是异构融合路线。

从并行编程视角看,如果你需要写 HIP(AMD 的类 CUDA 异构语言)代码,可以把它当成“CUDA 语法 + AMD 硬件细节”的组合。很多 CUDA 里的概念在 HIP 中几乎可以直接对应:__global__->__global__,__device__->__device__,__shared__->__shared__。但底层的调度单位、共享内存大小、寄存器分配策略都要以目标 AMD 芯片的手册为准。最常用的硬指标是gpuArch,比如gfx906、gfx908、gfx90a、gfx1100。你在编译 HIP 代码时,-t或--amdgpu-target需要写这些代号,所以记型号不如记 gfx 代号更直接。

3.3 为什么 AMD 的“架构对应芯片”更容易让人混淆

AMD 的历史包袱比较重。早期 Radeon 显卡型号本身不带架构信息,比如 RX 580、Radeon VII。Radeon VII 使用的是 Vega 20 核心,虽然代号里带 Vega,但它跟后来的 RX Vega 56/64 又不一样。等到 Instinct 系列出来,命名体系又重新洗牌。这让很多人直到今天也说不清 Radeon VII 和 MI50 之间的关系。其实它们都用 Vega 20 的核心,一个是消费级产品,一个是数据中心产品,底层的计算单元数量几乎相同,但驱动支持和指令集裁剪不一样。

因此我会建议 AMD 用户在做工程时,记住这几个“锚点”就够了:

  • Radeon VII 的 febf(摆在显存/带宽角度)相当于一张“能消费级的专业计算卡”,但软件支持已经比较老;
  • MI50 与 Radeon VII 同核心,足够用来研究 CDNA 前身架构;
  • RX 6900 XT 对应的 gfx1030,属于 RDNA 2,没有 Matrix Core;
  • MI250X 对应 gfx90a,属于 CDNA 2,有 Matrix Core 和强大的 FP64。

这些锚点之间互相映射,你在写 HIP 时就可以比较快地判断自己该针对哪套特性编程。还有一个非常实际的经验:AMD 的 GPU 被模拟或云服务暴露给用户时,名字往往不是品牌型号,而是类似 “AMD Instinct MI250 (gfx90a)” 这样的字符串。如果你不熟悉 gfx 代号,看到设备名会一头雾水。

4. 英特尔入局:Xe 架构看起来是“乱”,实际只有四条线

提到 GPU 并行编程,很多一线开发者默认只考虑 NVIDIA 和 AMD。但英特尔这几年在 GPU 生态上的投入越来越大,尤其是 Xe 架构的发布,让市场多了一个不可忽略的选项。Xe 架构并没有一个单一芯片打天下的思路,它分成几条不同的产品线,命名规则也很特殊,容易让人搞混。

对并行编程来说,英特尔架构对应的芯片型号可以分为四个主要层级:

  • Xe-LP(低功耗):用于核显和轻薄本,常见的是 Iris Xe 系列,集成在笔记本平台里。虽然规模小,但它完整支持 SYCL 和 oneAPI,很适合做入门级实验。
  • Xe-HPG(高性能图形):对应独立显卡 Arc 系列,型号有 A380、A580、A750、A770 等。这里的“A”应该是 Arc 的首字母,不是 Ampere 的 A,虽然看着像。Arc 卡的硬件特性面向游戏和常规图形计算,矩阵加速单元规模比数据中心版小。
  • Xe-HPC(高性能计算):对应 Ponte Vecchio,面向超算和 HPC 场景。早期这卡非常难搞,容量大,底层是把多颗 chiplet 组装在一起,细粒度上的线程调度和缓存一致性与普通架构不太一样。
  • Xe-HPG 之后的新演进:英特尔后续又有新的命名计划,比如 Arc Pro 系列用于专业工作站,内部的 Xe-Core 单元数量各不相同。

如果你准备在英特尔 GPU 上做并行编程,主流入口是 SYCL。英特尔的 Core i5 平台集显也能跑 SYCL,这非常适合没有独立显卡的人学习。但是注意,集显的 EU(Execution Unit)数量少,共享内存和本地内存的限制突出,你写的很多 kernel 在集显上会受限于占用率,这和张独显调优思路有区别。等到迁移到 A770 这种独立显卡上,行为又会变一大截,因为 EU 数量、缓存、带宽完全不同。

4.1 从芯片型号看英特尔的“EU 数量”和“内存布局”

英特尔的并行编程模型里最核心的硬件概念不是 SM 或 CU,而是 EU(执行单元)和 Subgroup。一个子群(Subgroup)在核显和独显上的实现宽度有区别,通常是 8 或 16。这意味着你在 OpenCL 或 SYCL 里设置nd_range的局部大小,或者考虑 subgroup 相关操作时,不能硬套 NVIDIA 的 32 线程思维。

以 Arc A770 为例,它有 32 个 Xe-Core,每个 Xe-Core 又包含多组 EU,整体硬件线程规模比同类价位的 NVIDIA 卡要低一点,但它有比较大的 L2 缓存和 GDDR6 显存带宽,在部分访存密集型任务上表现不错。与此同时,英特尔的工具有个显著优势:oneAPI 提供统一的device_selector,你可以用一个连续代码跑在 CPU、集成 GPU、独立 GPU 甚至 FPGA 上,这对学术研究和跨平台工程特别友好。

4.2 该拿英特尔卡做什么,不该做什么

我个人的经验是:英特尔 GPU 适合做并行编程学习和跨架构验证,不适合做需要极高生态兼容性的重型深度学习训练。PyTorch 在英特尔 GPU 上的支持虽然持续推进,但很多自定义 CUDA kernel 无法移植,必须重写成 SYCL 或其他跨架构语言。如果你有大量现成 CUDA 代码,期待它们无痛跑在 Arc 上,那是做梦。

但是,如果你是做新项目,且希望一次代码能部署到多厂商设备,SYCL + Xe-HPC 是一条有未来的路。某高校的并行计算课程里就用 Pablo/A770 加 SYCL 做大规模矩阵乘法实验,性能虽然打不过同价位 NVIDIA 卡,但整个工程的可读性和可移植性反而更好。

5. 从“芯片型号”到“代码优化”:架构特性最终是怎么决定 kernel 行为的

前面罗列了这么多型号和架构,可能有人会问:我写代码时又不会天天去看芯片型号,知道架构有什么用?这是个好问题。我可以说一个很典型的场景:你有一段 kernel,里面频繁使用__syncwarp()做束内同步,你想确认代码在未来的 GPU 上是否还能保持高性能,就要知道这张卡的 SIMD 宽度和锁步执行能力。不同芯片型号之间,即使架构代数相同,某些行为也会微妙的迁移。

5.1 计算能力决定“指令可用性”,而不是“能不能跑”

拿 CUDA 举例,你在代码里用了__shfl_xor_sync或者atomicAdd的某些特殊版本,编译成 PTX 后,它可以在较老的设备上通过 JIT 编译运行,但性能会严重下降。反过来,当你针对新架构的指令集(比如wgmma)编写后端时,老设备根本不能运行。这就是计算能力的作用:它决定的是“指令可用性”,不是简单的“能不能编译”。

如果要做一次最简单的验证,你可以在任意一台有 NVIDIA 卡的地方执行deviceQuery,查看输出里的CUDA Capability Major/Minor version number。手动做一个映射:如果 minor 版本提高,代表同主架构中引入了更宽松的硬件特性,比如 Ampere 的 8.6 表面上比 8.0 只多了 0.6,但你要是去查CUDA C++ Programming Guide会发现,8.6 的硬件多了一些整数点积和低精度浮点指令。那些运算在 8.0 上必须以多指令模拟,自然慢。

5.2 选择 kernel 并行粒度时,芯片型号是隐藏参数

我说一个我做并行归约时踩过的坑。当时我用一张 RTX 3090 做基准测试,采用一个 workgroup 内 256 个线程、每线程处理 8 个元素的归约策略,性能不错。后来同样的代码迁移到 V100 上,直接掉了 40%。原因倒不是 V100 的算力差,而是我的策略是按照 Ampere 的 32-lane warp 和较新的寄存器能力来设计的;在 Volta 上,warp 调度和 shared memory 带宽不同,加上 L2 大小差异显著,归约的访存局部性变差了。

所以性能优化不能只针对算法本身,还要针对目标芯片型号做变体生成。工业级别的库,比如 cuBLAS、rocBLAS、oneMKL,内部都会对不同芯片分派不同 kernel。这也是为什么开源社区常见做法是提供-arch参数多个编译 target,甚至运行时检查deviceProp来选择不同调优策略。

5.3 显存大小和带宽:最容易被忽略的“架构差异”

并行编程里很多工作负载其实是访存受限,不是计算受限。此时决定内核上限的因素不是 SM 数量,而是显存带宽和缓存。看芯片型号时,不能只看核心数,还要注意它的显存位宽和带宽。

举个例子:

  • RTX 4070 Ti:192-bit 位宽,显存带宽约 504 GB/s。
  • RTX 3090:384-bit 位宽,显存带宽约 936 GB/s。
  • A100:5120-bit 位宽(HBM2e),带宽约 1555 GB/s(80GB 版本是 2039 GB/s)。
  • H100:更巨大,超过 3TB/s。

如果你是在做大矩阵乘法、图像卷积这类访存密集型运算,按理说 RTX 4070 Ti 核心不算少,但带宽限制会拖后腿。如果你是在做纯计算密集型任务,比如大型 Monte Carlo 模拟,核心频率和 SM 数量反而是敏感参数。所以看到芯片型号时,一定要习惯性地把显存带宽同步查出来。

我的经验做法是:在写 kernel 之前,先估算一遍该芯片的理论计算峰值和访存带宽,然后算一下arithmetic intensity(算术强度)。如果算法达到或超过 machine balance,再做优化时就要全力提升计算密集度;如果 arithmetic intensity 小于 balance,那你哪怕优化到天上去,也很难突破带宽瓶颈。这张“芯片型号 - 硬件参数”表,就是做算术强度估算的基础。

6. 继续往下走之前,需要记住的几件事

这一章内容跨度有点大,从 NVIDIA 到 AMD 再到 Intel,从数据中心卡到消费级卡,到英特尔的 Xe 架构小体系。我不想给你一个过于冗长的总结清单,因为 GPU 硬件本身的迭代速度很快,今天写着 A100,明年可能就被 H200、B200 取代。记住一些稳定的原则,比记住具体型号更重要。

第一,把每个芯片型号和它的架构代号、计算能力(CUDA)或 gfx 代号(AMD)绑定起来。你不需要背所有 SKU,但至少要能根据一张新卡的型号,判断出它属于哪一代架构。要做到这一点,最快的方法是建立一张自己填写的表:型号、架构、核心数、显存带宽、FP64 能力、NVLink/互联方式、推荐用途。这样等你拿到一张陌生卡时,可以很快定位它的大致性能区间。

第二,要区分“能跑”和“能跑得快”。很多架构差异,尤其是 Tensor Core、Matrix Core、Matrix 加速单元、DPX 指令等,只影响特定计算负载。如果你的负载用不上这些特殊指令,那么上述差异对你的代码影响很小。但如果你要做 AI 推理、大模型训练或数值计算,这些特性就是决定成败的关键。所以优化动作一定要贴合目标架构的指令特性,而不能无条件相信“同一行代码在新卡上一定更快”。

第三,多平台开发时,要尽早做抽象。现在跨架构编程的选项越来越多,SYCL、HIP、OpenCL 都可以帮助你屏蔽一部分硬件差异。但抽象层本身也有成本,比如 HIP 在 AMD 卡上很顺,但要做到跨 NVIDIA 的高性能,仍需要维护两套后端优化。如果项目是长期维护的,建议把公共逻辑和厂商专用扩展分开,这样当某张新卡发布后,你可以只修改底层适配层,而不是把整个应用推倒重来。

第四,遇到“型号对应不上”的困惑时,老办法永远有效:直接查设备属性。NVIDIA 用cudaGetDeviceProperties,AMD 用hipGetDeviceProperties,Intel 用 SYCL 里的device::get_info。设备属性里面包含了芯片型号字符串、计算能力、内存大小、最大 block 尺寸、warp 或 subgroup 大小、显存带宽、L2 缓存、统一内存等关键信息。虽然在文章里讨论芯片型号会显得玄学,但在工程现场,最靠谱的永远是设备返回的值,而不是网上的测评文章。

最后分享一点我在做 GPU 并行开发时的小习惯:每次拿到一张新卡,我都会先跑一遍官方提供的deviceQuery和bandwidthTest,然后再跑一个自己写的小矩阵乘法/向量归约 benchmark,记录到本地表格里。这样几周后回头继续选型或调优时,已经有现成的基线数据,不用再去翻规格书。尤其是当你想优化某一个 kernel,却不知道瓶颈到底在访存还是在计算时,这个基线数据能帮你迅速定位。

这一章是打通“硬件认知”和“软件编程”的关键一环。后面如果再聊更底层的并行策略,比如怎么用 shared memory 实现高效归约、怎么用异步拷贝隐藏延迟、怎么构造适合 tensor core 的数据布局,都会默认你已经建立了这套架构和芯片型号之间的映射关系。你可以先把这张对照表消化下来,找手头的卡跑一跑deviceQuery,看看你现在写的 kernel 是不是还有硬件特性没利用上。这一步做完,你就真正从“会写 CUDA 代码”进阶到“知道自己为什么这么写了”。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询