1、GPU架构概述:GPU发展简史、GPU vs CPU核心差异、现代GPU通用架构

各位同学好,我是老张。今天咱们开始这门课的第一讲。说实话,每次讲GPU架构我都挺感慨的——从当年做图形加速的小芯片,到现在撑起AI半壁江山的算力核心,这发展速度真是让人跟不上。嗯,咱们先捋一捋它的发展脉络。

1.1 GPU发展简史:从图形卡到通用计算引擎

GPU的历史,说白了就是一部「从专用走向通用」的进化史。

  • 1990年代:固定功能管线时代
    那时候的GPU叫「图形加速卡」,只能干固定的事——画三角形、贴纹理、做光栅化。我记得刚入行时调过一块S3 Virge的板子,为了让它正确显示一个旋转的茶壶,折腾了整整一周。你想想看,那时候的GPU连可编程都谈不上,更别提通用计算了。
  • 2001-2006年:可编程着色器出现
    NVIDIA的GeForce 3引入了顶点着色器和像素着色器。这是个转折点——程序员终于能写点自己的代码跑在GPU上了。不过那时候的编程模型还很别扭,你得用图形API(比如DirectX)去「伪装」通用计算。我在项目中试过用像素着色器做矩阵乘法,那代码写得...嗯,现在回头看简直是行为艺术。
  • 2007年至今:统一架构与通用计算爆发
    NVIDIA的G80架构(GeForce 8800 GTX)是个里程碑。它把顶点着色器和像素着色器合并成了统一的流处理器(CUDA Core),并且推出了CUDA编程模型。从此GPU不再是「图形卡」,而是真正的「通用并行处理器」。我2010年参与过一个气象模拟项目,用CUDA把计算时间从3天缩短到4小时——那种震撼感,到现在都记得。

关键转折点: 2007年CUDA的发布,让GPU从「图形加速器」变成了「通用并行计算平台」。没有这一步,今天的AI浪潮根本不可能发生。

1.2 GPU vs CPU核心差异:为什么GPU能跑这么快?

很多人问我:「老张,GPU和CPU到底差在哪?为什么CPU不能像GPU那样并行?」

这个问题,咱们从三个维度来看:

维度 CPU GPU
设计目标 低延迟、串行执行、复杂控制 高吞吐、并行执行、简单控制
核心特点 大缓存、强分支预测、乱序执行 大量ALU、小缓存、SIMT执行模型
典型面积分配 控制逻辑占40%,缓存占40%,ALU占20% 控制逻辑占10%,缓存占10%,ALU占80%
适用场景 操作系统、数据库、交互应用 矩阵运算、图像处理、深度学习

为什么会这样?

CPU的设计哲学是「把一件事做到最快」。它花大量晶体管在分支预测、乱序执行、大容量缓存上——就是为了让单线程跑得飞快。你想想看,操作系统调度、数据库查询、Web服务器响应,这些任务本质上都是串行的,而且充满了分支和依赖。

GPU的设计哲学是「同时做一万件简单的事」。它把绝大部分晶体管都给了ALU(算术逻辑单元),控制逻辑和缓存能省则省。每个CUDA Core都很「笨」——它不会乱序执行,不会做复杂的分支预测,但它有几千个这样的「笨核心」同时干活。

我的经验: 判断一个任务适不适合GPU,就看它能不能被拆成大量独立的小任务。如果任务之间有大量数据依赖或分支,那CPU反而更快。我曾经见过有人硬要把链表遍历放到GPU上跑,结果比CPU还慢10倍——这就是典型的「用错工具」。

1.3 现代GPU通用架构:SM/CU、内存层次、互联总线

好,咱们来看看现代GPU到底长什么样。以NVIDIA的架构为例(AMD的类似,只是叫法不同):

1.3.1 SM/CU:计算的基本单元

SM(Streaming Multiprocessor,流式多处理器)是GPU的核心计算单元。一个GPU芯片里有几十到上百个SM。

每个SM内部包含:

  • CUDA Core(核心):执行整数和浮点运算。一个SM通常有64-128个。
  • 共享内存(Shared Memory):SM内部的高速存储,容量小(几十KB到上百KB),但延迟极低。
  • 寄存器文件(Register File):每个线程的私有存储,容量有限(每个线程最多255个寄存器)。
  • Warp调度器:负责把32个线程组成一个Warp,并调度执行。

这里有个关键概念——SIMT(单指令多线程)。说白了就是:32个线程(一个Warp)执行同一条指令,但操作不同的数据。这和CPU的SIMD(比如AVX指令)有点像,但更灵活——每个线程可以有自己的寄存器、自己的地址计算。

避坑指南: 我曾经在项目中遇到过一个性能问题——某个kernel的occupancy(占用率)只有25%。查了半天才发现,是因为每个线程用了太多寄存器,导致SM能同时容纳的线程数大幅减少。记住:寄存器是稀缺资源,别滥用。

1.3.2 内存层次结构:速度与容量的博弈

GPU的内存层次和CPU类似,但更「极端」:

层级 容量 带宽 延迟 作用域
寄存器 每个线程最多255个 极高 1个周期 线程私有
共享内存 每个SM 48-96KB 极高 ~20个周期 Block内共享
L1缓存 每个SM 128-256KB ~30个周期 SM私有
L2缓存 整个芯片 4-40MB 中等 ~200个周期 芯片共享
全局内存(HBM/GDDR) 16-80GB 1-2TB/s ~400-800个周期 所有线程

嗯,这里要注意:全局内存的带宽虽然高(HBM2e能到2TB/s),但延迟也高得吓人。所以优化的核心思路就是——尽量把数据往上层搬

我个人的习惯是:先看数据能不能放共享内存,再看能不能用寄存器。实在不行才去访问全局内存。而且访问全局内存时,一定要保证合并访问(Coalesced Access)——也就是相邻的线程访问相邻的地址。否则带宽利用率会惨不忍睹。

1.3.3 互联总线:把芯片串起来

现代GPU不是单打独斗的。一个GPU芯片内部有多个GPC(图形处理簇),每个GPC包含多个SM。它们之间通过片上互联(比如NVIDIA的NVLink或AMD的Infinity Fabric)连接。

多GPU之间呢?

  • PCIe总线:最通用的互联方式,但带宽有限(PCIe 4.0 x16约32GB/s)。
  • NVLink:NVIDIA的高速互联,带宽可达PCIe的5-10倍。我去年调过一个8卡DGX系统,NVLink的带宽确实给力——但编程复杂度也上去了。
  • Infinity Fabric:AMD的方案,类似NVLink,但更开放。

性能建模的关键: 在做GPU性能建模时,千万别只盯着计算单元。很多时候瓶颈在内存带宽或互联总线上。我见过太多人把kernel优化到极致,结果发现数据搬运的时间比计算还长——这就是典型的「木桶效应」。

小结

这一章咱们聊了GPU的来龙去脉、和CPU的本质区别、以及现代GPU的三大核心组件:SM/CU、内存层次、互联总线。

下一章咱们会深入SM内部,看看Warp调度、指令发射、以及那些让GPU「又爱又恨」的分支发散问题。嗯,到时候我会分享一个我踩过的坑——一个看似简单的if-else语句,让性能掉了60%。

今天就到这儿。有问题随时问我。


公众号:蓝海资料掘金营,微信deep3321