1、GPU计算概述:GPU与CPU架构对比、GPU计算发展史、GPU应用场景

大家好,我是你们这门课的主讲。咱们今天聊聊GPU计算的开篇——说白了,就是搞清楚GPU到底是个什么玩意儿,它凭什么能跑得这么快。

我最早接触GPU计算是在2012年,那时候还在做物理模拟。当时用CPU算一个流体仿真,跑一晚上都出不来结果。后来有同事建议我试试CUDA,我一开始还不太信——一个显卡能有多大能耐?结果第一次跑通的时候,我盯着屏幕愣了好几秒。嗯,从那以后我就再也没小看过GPU。

1.1 GPU与CPU架构对比

先问大家一个问题:CPU和GPU,到底差在哪?

你想想看,CPU就像是一个全能型选手——它能处理各种复杂的任务,逻辑判断、分支预测、乱序执行,样样都行。但它的核心数量有限,一般桌面级CPU也就8核16线程,服务器级的也就几十个核。

GPU就不一样了。它更像是一支军队——单个士兵的战斗力可能不如CPU那个全能选手,但架不住人多啊!一块现代GPU动辄几千个核心,比如NVIDIA的H100有18432个CUDA核心。这是什么概念?就是你可以同时让上万个线程干活。

我习惯用这个比喻来理解:

  • CPU:法拉利跑车——跑得快,但一次只能拉两个人
  • GPU:大卡车——跑得慢点,但一次能拉几十吨货

具体到架构层面,差异就更明显了:

对比维度 CPU GPU
核心数量 几个到几十个 几千个
控制单元 复杂(分支预测、乱序执行) 简单(顺序执行为主)
缓存大小 大(L1/L2/L3,几十MB) 小(L1/L2,几MB)
内存带宽 几十GB/s 几百到几千GB/s
适用场景 串行任务、复杂逻辑 并行任务、数据密集

核心要点:GPU之所以快,靠的不是单个核心的性能,而是「人多力量大」。它牺牲了单个线程的复杂度,换来了海量的并行度。

1.2 GPU计算发展史

GPU的发展史,其实挺有意思的。我把它分成三个阶段来讲:

第一阶段:图形专用期(1990s - 2006)

早期的GPU就是专门用来画图的。那时候叫「图形加速卡」,主要干的事就是把3D模型变成屏幕上的像素。程序员想用它做别的?没门。它只认图形API(OpenGL、DirectX)。

我记得2003年的时候,有个叫Brook的项目,尝试用GPU做通用计算。当时得把计算问题伪装成图形渲染——把数据塞进纹理,把计算写成像素着色器。那叫一个别扭!

第二阶段:通用计算觉醒期(2007 - 2015)

2007年,NVIDIA发布了CUDA。这玩意儿是个分水岭。它让程序员可以用C语言直接写GPU程序,不用再跟图形API较劲了。

我当时第一次用CUDA写矩阵乘法,代码大概长这样:

__global__ void matmul(float *A, float *B, float *C, int N) {
    int row = blockIdx.y * blockDim.y + threadIdx.y;
    int col = blockIdx.x * blockDim.x + threadIdx.x;
    
    float sum = 0.0f;
    for (int k = 0; k < N; k++) {
        sum += A[row * N + k] * B[k * N + col];
    }
    C[row * N + col] = sum;
}

你看,这不就是普通的C代码加了个__global__修饰符吗?门槛一下子就降下来了。

第三阶段:遍地开花期(2016 - 至今)

2016年之后,GPU计算彻底爆发了。原因很简单——深度学习火了。训练神经网络需要海量的矩阵运算,这正好是GPU的强项。

现在GPU的应用已经远远超出了图形和AI。科学计算、金融建模、分子动力学、气象预报……你能想到的算力密集型领域,基本都有GPU的身影。

个人经验:我建议初学者不要一上来就啃CUDA编程指南。先理解GPU的「并行思维」——把一个大任务拆成成千上万个独立的小任务,每个线程只管自己那一小块。想通了这一点,后面学起来就顺了。

1.3 GPU应用场景

说到应用场景,我挑三个最典型的来讲:

AI与深度学习

这是目前GPU最大的应用市场。训练一个GPT-4级别的模型,需要上万块GPU跑好几个月。为什么非GPU不可?因为神经网络的核心操作就是矩阵乘法和卷积,这些操作天然就是并行的。

举个例子,一个全连接层:

// 伪代码:一个线程计算输出层的一个神经元
int tid = threadIdx.x;
float sum = 0;
for (int i = 0; i < input_size; i++) {
    sum += input[i] * weight[tid * input_size + i];
}
output[tid] = activation(sum);

每个线程独立计算一个输出神经元,互不干扰。这就是GPU最擅长的模式。

科学计算

我在做物理模拟的时候,经常要解偏微分方程。用有限差分法把空间离散化之后,每个网格点的计算只依赖相邻的几个点。这种「局部性」特别适合GPU。

比如流体模拟中的NS方程求解,用GPU加速后,速度提升可以达到50-100倍。以前算一个3D流场要等一整天,现在喝杯咖啡的功夫就出结果了。

图形渲染

别忘了,GPU的老本行就是图形渲染。现在的光线追踪技术,就是靠GPU的并行能力才能实时渲染出逼真的光影效果。

每个像素的光线追踪计算是独立的——这又是一个天然的并行任务。所以你看,GPU的架构设计从一开始就抓住了这个本质:能并行的,绝不串行

避坑指南:我曾经犯过一个错误——把CPU上的优化思路直接搬到GPU上。比如在CPU上,我们会尽量复用数据,减少内存访问。但在GPU上,有时候「重复计算」反而比「从全局内存读数据」更快。因为GPU的计算单元多,但内存带宽相对有限。这个思维转换,很多新手都会栽跟头。

小结

好了,这一章的内容就这些。总结一下:

  • GPU和CPU的架构差异,本质是「多而简」vs「少而精」
  • GPU计算从图形专用走到通用计算,CUDA是关键转折点
  • AI、科学计算、图形渲染是GPU的三大主战场

下一章我们会深入GPU的编程模型,聊聊线程、块、网格这些概念到底是怎么回事。到时候我会拿一个实际项目中的例子来拆解,保证让你一听就懂。

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