1. CUDA是什么:从GPU到通用计算,CUDA的诞生背景与历史
聊CUDA之前,我想先问你一个问题:
你第一次听说GPU是用来做通用计算的时候,是什么反应?
我记得2007年我刚入行那会儿,听到有人说“用显卡跑科学计算”,第一反应是——这玩意儿不是打游戏的吗?
嗯,今天回过头来看,这个转变其实挺有意思的。
它背后藏着整个AI芯片产业的底层逻辑。
1.1 GPU的“前世”:为图形而生
GPU的全称是Graphics Processing Unit,图形处理器。
它最早的设计目标只有一个:把3D场景快速渲染到屏幕上。
你想想看,一个游戏画面里,几百万个三角形要同时做坐标变换、光照计算、纹理映射……
CPU那种“一个核跑一个线程”的架构,根本扛不住。
所以GPU走了另一条路:堆大量的小核心,每个核心能力不强,但胜在数量多、并行度高。
我早期做图形驱动开发的时候,接触过NVIDIA的GeForce 6系列。
那时候的GPU,核心数已经上百了,但每个核心只能做简单的浮点运算。
说白了,它就是一台“专为矩阵乘法优化的机器”。
1.2 转折点:为什么有人想用GPU做通用计算?
大概在2003年左右,一些搞科研的人发现了一个“歪门邪道”:
他们用OpenGL或者DirectX的图形API,把科学计算伪装成图形渲染,塞进GPU里跑。
结果发现——速度比CPU快了一个数量级。
为什么会这样?
因为很多科学计算,本质上就是大规模矩阵运算。
比如分子动力学模拟、气象预报、石油勘探……这些任务里,数据量大、计算模式单一,正好撞在GPU的枪口上。
但问题也很明显:
你得把计算问题“翻译”成图形问题。
你得用顶点着色器、片段着色器这些图形概念去编程。
我有个朋友当年做流体力学模拟,为了用GPU加速,硬是学了三个月的图形学API——他说那感觉就像“用螺丝刀当筷子使”。
1.3 CUDA的诞生:把GPU变成“通用计算引擎”
2006年,NVIDIA做了一件改变行业的事:
他们发布了CUDA(Compute Unified Device Architecture)。
说白了,就是给GPU装上了一套“通用计算”的编程接口。
你不再需要学OpenGL了。
你只需要用C语言(后来是C++、Python)写一个函数,叫“kernel”,然后告诉CUDA:“这个函数,给我在GPU上跑一万次。”
剩下的——线程调度、内存管理、数据传输——CUDA全帮你搞定。
我记得第一次用CUDA写向量加法的时候,代码大概长这样:
// 一个简单的CUDA kernel
__global__ void vecAdd(float* A, float* B, float* C, int N) {
int i = threadIdx.x + blockIdx.x * blockDim.x;
if (i < N) {
C[i] = A[i] + B[i];
}
}
// 调用方式
vecAdd<<<numBlocks, blockSize>>>(d_A, d_B, d_C, N);
你看,代码本身和C语言几乎没区别。
唯一的区别就是那个 <<<...>>> 语法——它告诉CUDA:启动多少个线程块,每个块里有多少线程。
这个设计有多重要?
我打个比方:
以前你想用GPU,得自己造一辆车(学图形API)。
CUDA给了你一辆现成的车,你只需要学会踩油门(写kernel)。
1.4 CUDA的生态:从工具到护城河
CUDA刚出来的时候,其实并不被看好。
AMD有Stream SDK,Intel有Larrabee,大家都在抢这个市场。
但为什么最后只有CUDA活下来了?
我觉得有三个原因:
- 先发优势:2006年发布,比对手早了至少两年。这两年足够NVIDIA把开发者圈住。
- 持续投入:NVIDIA每年在CUDA上的研发投入,据说超过10亿美元。他们不光做编译器、调试器,还做了cuBLAS、cuFFT、cuDNN这些库——你直接调用就行,不用自己写底层。
- 社区生态:从学术论文到工业应用,CUDA成了“GPU计算”的代名词。你发论文用CUDA,审稿人默认接受;你用OpenCL,还得解释半天。
我2012年参加GTC大会的时候,NVIDIA的CEO黄仁勋说过一句话,我到现在还记得:
“CUDA不是一种编程语言,它是一种思维方式。”
当时觉得这话有点虚,现在回头看——确实如此。
1.5 一张图看懂CUDA的架构
下面这张图,是我自己画的CUDA核心架构图。
它展示了从CPU到GPU的调用流程:
这张图想表达的核心逻辑是:
CPU负责串行控制,GPU负责并行计算。
数据从CPU传到GPU,GPU用成千上万个线程并行处理,最后把结果传回CPU。
你注意看中间的“Grid”和“Block”——这是CUDA的线程层次结构。
一个Grid包含多个Block,一个Block包含多个Thread。
这种两级结构,是为了适配GPU的硬件架构:Block内的线程可以共享内存,Block之间则相对独立。
1.6 避坑指南:我踩过的几个坑
讲到这里,我想分享几个我早期用CUDA时踩过的坑:
- 坑一:忘记同步 —— 我曾经写过一个kernel,多个Block同时写同一个全局变量,结果数据全乱了。后来加了
__syncthreads()才解决。 - 坑二:内存分配太小 —— GPU的显存是有限的。我有个项目需要处理4K视频帧,结果显存爆了。后来改用“分块处理”才搞定。
- 坑三:过度优化 —— 刚开始总想着把每个循环都并行化,结果发现有些任务串行更快。记住:不是所有问题都适合GPU。
1.7 小结:CUDA为什么是AI芯片的“护城河”?
回到我们课程的主题。
CUDA的诞生,本质上解决了一个核心问题:
如何让开发者用最小的学习成本,获得GPU的并行计算能力。
这个问题的答案,决定了NVIDIA在AI芯片领域的统治地位。
因为AI训练和推理,本质上就是大规模矩阵运算——这正是CUDA最擅长的事情。
你想想看,现在搞AI的工程师,有几个不会用PyTorch或TensorFlow?
而这些框架底层,调的就是cuDNN、cuBLAS这些CUDA库。
一旦开发者习惯了这套生态,就很难再切换到其他平台了。
这就是护城河。
不是硬件本身,而是硬件之上的软件生态。
公众号:蓝海资料掘金营,微信deep3321