1、GPU的前世今生:从图形卡到通用计算巨人
说实话,每次有人问我“GPU到底是什么”,我总想先讲个故事。
1999年,NVIDIA发布了GeForce 256。那是我第一次听说“GPU”这个词。当时我还在学校,觉得这玩意儿就是打游戏用的。谁能想到,二十多年后,我会用它来跑深度学习模型,做科学计算?
嗯,今天我们就聊聊这段历史。从图形卡到通用计算巨人,GPU到底经历了什么?
1.1 图形卡的诞生:为什么需要专门的图形硬件?
早期的计算机,图形显示全靠CPU。你想想看,CPU要处理逻辑运算、控制流程,还得管屏幕上每个像素的颜色。这活儿太杂了。
我记得90年代初,一台486电脑要显示一个3D立方体,CPU得算半天。旋转一下,画面就卡成PPT。为什么会这样?因为CPU是串行处理器,擅长的是“一件事一件事地做”。但图形渲染呢?它需要同时处理成千上万个像素。
于是,图形加速卡出现了。说白了,就是把渲染这件事从CPU手里抢过来,交给专门的硬件去做。
关键转折点:1997年,3dfx的Voodoo显卡让3D游戏真正火了起来。它用硬件实现了纹理映射、Z缓冲这些基础操作。我当年为了玩《雷神之锤》,攒了三个月零花钱买了块Voodoo2——嗯,那感觉,比现在买RTX 4090还兴奋。
1.2 从固定管线到可编程着色器
早期的图形卡,功能是固定的。你给它一个三角形,它帮你画出来。你想加点特殊效果?抱歉,硬件不支持。
2001年,NVIDIA的GeForce 3引入了可编程着色器。这是个里程碑。什么意思呢?就是开发者可以自己写一小段程序,控制顶点和像素的处理方式。
我个人觉得,这是GPU走向通用计算的第一个伏笔。虽然当时大家还只想着做光影特效,但“可编程”这三个字,打开了潘多拉的盒子。
| 年代 | 代表产品 | 关键特性 |
|---|---|---|
| 1999 | GeForce 256 | 首个GPU,硬件T&L |
| 2001 | GeForce 3 | 可编程顶点/像素着色器 |
| 2006 | GeForce 8800 GTX | 统一着色器架构 |
| 2007 | CUDA 1.0 | 通用计算正式登场 |
1.3 统一着色器架构:GPU的“觉醒”
2006年之前,GPU里的顶点着色器和像素着色器是分开的。顶点多的时候,像素单元闲着;像素多的时候,顶点单元闲着。浪费啊!
GeForce 8800 GTX做了一个大胆的决定:把所有着色器统一起来。每个计算单元既能处理顶点,也能处理像素。这听起来简单,但背后是硬件调度的大变革。
我当年在项目中调试一个图形渲染管线,就遇到过这种负载不均的问题。顶点着色器忙得要死,像素着色器却在“摸鱼”。统一架构之后,调度器可以动态分配任务,效率提升了一大截。
我的经验:统一着色器架构的本质,是把GPU变成了一个“大规模并行计算平台”。每个计算单元都是通用的,只是被调度去执行不同的任务。这个思想,后来直接催生了CUDA。
1.4 CUDA的诞生:从图形到计算的跨越
2007年,NVIDIA发布了CUDA。说实话,当时很多人不看好。包括我自己,也觉得“用显卡做计算?太折腾了吧”。
但CUDA做对了一件事:它让程序员可以用C语言写GPU程序。不需要学图形API,不需要懂渲染管线。你写一个循环,CUDA帮你把它拆成成千上万个线程,扔到GPU上并行执行。
为什么会成功?因为GPU的架构天生适合数据并行。一个矩阵乘法,CPU要串行算,GPU可以同时算。你想想看,1000x1000的矩阵,CPU可能要几秒,GPU只要几毫秒。
避坑指南:我曾经以为CUDA程序就是“把循环改成并行”这么简单。结果第一次跑的时候,性能还不如CPU。后来才发现,数据在CPU和GPU之间来回拷贝,开销巨大。记住:减少数据传输,才是优化的第一步。
1.5 GPU架构的核心:SIMT与线程调度
说到GPU计算,就绕不开SIMT(单指令多线程)。这是GPU和CPU最本质的区别。
CPU是MIMD(多指令多数据),每个核心可以执行不同的指令。GPU是SIMT,一组线程执行同一条指令,但处理不同的数据。
举个例子:你要给1000个像素加亮度。CPU的做法是:循环1000次,每次加一个。GPU的做法是:启动1000个线程,每个线程加一个像素。所有线程同时执行“加法”指令,但操作的数据不同。
嗯,这里要注意:SIMT不是简单的SIMD。SIMD要求数据对齐,长度固定。SIMT更灵活,每个线程可以有自己的寄存器、自己的地址计算。这也是为什么GPU编程比SIMD编程更友好。
// CPU版本:串行
for (int i = 0; i < 1000; i++) {
pixels[i] += 10;
}
// GPU版本:并行
__global__ void add_brightness(int* pixels) {
int idx = threadIdx.x + blockIdx.x * blockDim.x;
pixels[idx] += 10;
}
你看,GPU版本里,每个线程只处理一个像素。1000个线程同时跑,速度自然快。
1.6 从G80到Hopper:架构演进路线
这些年,GPU架构一直在进化。我简单梳理一下关键节点:
- G80 (2006):统一着色器,CUDA的硬件基础
- Fermi (2010):真正的通用计算架构,支持ECC、双精度
- Kepler (2012):动态并行,GPU可以自己启动新线程
- Maxwell (2014):能效比大幅提升,我开始用它跑深度学习
- Volta (2017):Tensor Core,专门为AI设计的矩阵计算单元
- Hopper (2022):Transformer引擎,为大型语言模型优化
我个人觉得,Volta是最重要的一代。Tensor Core的出现,让GPU从“通用计算”又进化到了“AI专用计算”。现在你训练GPT、Stable Diffusion,靠的就是这些Tensor Core。
1.7 知识体系总览
下面这张图,是我自己整理的GPU发展脉络。你可以看到,从图形卡到通用计算,再到AI加速,GPU的每一步进化都有清晰的逻辑。
1.8 我的感悟
回顾GPU这二十多年的发展,我觉得最有趣的是:每一次“专用”到“通用”的转变,都带来了新的可能性。
图形卡是专用的,但可编程着色器让它变得通用了一点。统一架构让计算单元更通用,CUDA让编程模型更通用。然后Tensor Core又回到了“专用”——专门为AI计算设计。
这不是倒退,而是螺旋式上升。每一次“专用”,都是在上一轮“通用”的基础上,针对新需求做的极致优化。
嗯,这就是GPU的前世今生。从打游戏到跑AI,它走过的路,比我们想象的更精彩。
一句话总结:GPU的进化史,就是一部“如何让更多计算单元更高效地并行工作”的历史。理解了这一点,你就抓住了GPU架构的精髓。
公众号:蓝海资料掘金营,微信deep3321