计算基础与数据流:计算机体系结构回顾、数据流架构(SIMD/SIMT/MIMD)、AI计算的核心模式

大家好,我是你们的老朋友。今天咱们聊聊AI芯片最底层的那些事儿——计算基础与数据流。说实话,很多做AI应用的同学,对这块儿往往是一知半解。但你想啊,不理解计算机怎么干活,你怎么能指望它帮你把模型跑得飞快呢?

我个人习惯,讲任何架构之前,先回到最根本的计算模型上。咱们从冯·诺依曼结构说起,一步步走到今天AI芯片里那些眼花缭乱的数据流架构。

1. 计算机体系结构回顾:从冯·诺依曼到瓶颈

冯·诺依曼结构,说白了就是“存储程序”的概念。指令和数据放在同一个存储器里,CPU一条条取出来执行。这个模型统治了计算机半个多世纪。

但问题来了——CPU和内存之间的速度差距越来越大。这就是著名的“冯·诺依曼瓶颈”。我在做第一代AI加速器的时候,就深刻体会到了这一点。当时我们用的DDR3内存,带宽才十几GB/s,而计算单元的理论吞吐已经奔着几百GFLOPS去了。结果呢?计算单元大部分时间都在等数据,利用率惨不忍睹。

核心矛盾:计算单元越来越快,但数据搬运的速度跟不上。AI计算又是典型的数据密集型任务,这个矛盾被无限放大了。

所以,现代AI芯片的设计哲学,很大程度上就是在跟这个瓶颈作斗争。怎么斗?两种思路:一是让计算靠近数据(近存计算),二是让数据流动起来(数据流架构)。

2. 数据流架构:SIMD / SIMT / MIMD

数据流架构,说白了就是“数据驱动计算”。指令不再是一条条顺序执行,而是等数据准备好了,计算就自动触发。这个思想在AI芯片里被玩出了花。

咱们先看几个经典模型:

架构 全称 核心思想 典型代表
SIMD 单指令多数据 一条指令,同时对多个数据执行相同操作 CPU的MMX/SSE/AVX指令集
SIMT 单指令多线程 多个线程执行同一条指令,但每个线程处理不同数据 NVIDIA GPU的CUDA核心
MIMD 多指令多数据 多个处理器各自执行不同指令,处理不同数据 多核CPU、分布式系统

SIMD 是最朴素的形式。我记得第一次用SSE指令集做向量加法时,感觉就像打开了新世界的大门——一条指令顶四条,效率直接翻四倍。但它的局限性也很明显:所有数据必须对齐,操作必须完全一致。一旦出现分支,性能就崩了。

SIMT 是GPU的杀手锏。它本质上是对SIMD的一种“软化”。每个线程看起来是独立的,有自己的程序计数器,但实际上硬件会把多个线程打包成“warp”(NVIDIA的叫法)或“wavefront”(AMD的叫法),一起执行。这样做的好处是:程序员不用操心数据对齐,编译器帮你搞定。坏处是:如果warp里的线程走了不同分支,那就得串行执行,性能直接腰斩。

避坑指南:我曾经在优化一个卷积算子时,发现GPU利用率死活上不去。后来一查,原来是warp里有一半线程在算边界填充,另一半在算正常区域。分支发散导致warp串行化,性能直接掉了40%。所以,写GPU代码时,一定要尽量避免warp内的分支。

MIMD 则是最灵活的模式。每个核心可以独立执行不同的任务。多核CPU就是典型的MIMD。但在AI场景下,MIMD的灵活性反而成了负担——因为AI计算的核心模式是“同构计算”,所有层都在做类似的事情(矩阵乘、卷积、激活),用MIMD反而浪费了控制逻辑。

3. AI计算的核心模式:矩阵乘与卷积

AI计算,说白了就是两个核心操作:矩阵乘法和卷积。其他什么全连接、注意力机制、Transformer,底层拆开来看,都是这两个东西的变种。

矩阵乘法 是神经网络的基础。一个全连接层,就是输入向量乘以权重矩阵。一个Transformer的注意力头,就是Q乘以K的转置。矩阵乘法的计算模式是:

C[m][n] = Σ A[m][k] * B[k][n]

这个操作的特点是:数据复用率高。A矩阵的一行会被B矩阵的所有列复用,B矩阵的一列会被A矩阵的所有行复用。所以,好的数据流设计,就是要最大化这种复用,减少数据搬运。

卷积 则是CNN的核心。它的计算模式是:

O[oh][ow] = Σ I[ih][iw] * K[kh][kw]

卷积的特点是:权重复用。同一个卷积核会在输入特征图上滑动,被反复使用。我在做卷积加速器时,最喜欢用的策略就是“权重驻留”——把卷积核数据留在片上缓存里,只搬运输入和输出数据。这样能省掉大量的片外带宽。

核心洞察:AI计算的数据流设计,本质上就是在回答三个问题:

  • 数据从哪里来?(片外DRAM还是片上SRAM?)
  • 数据往哪里去?(计算单元还是下一级存储?)
  • 数据怎么复用?(时间复用还是空间复用?)

4. 数据流架构在AI芯片中的实践

好了,理论说完了,咱们看看实际芯片里是怎么做的。

以Google的TPU为例,它采用的是脉动阵列(Systolic Array)架构。说白了,就是把一堆乘加单元排成二维阵列,数据像流水一样在阵列里“脉动”流动。每个单元只跟邻居通信,没有全局连线。这样做的好处是:数据局部性极好,带宽需求低。

我记得第一次看TPU论文时,被那个128x128的脉动阵列震撼到了。每个周期,阵列能完成16384次乘加操作。而数据只需要从片外读一次,然后在阵列里反复流动。这就是数据流架构的威力。

再比如NVIDIA的GPU,它采用的是SIMT + 共享内存的组合。每个SM(流多处理器)内部有一块共享内存,可以被同一block的所有线程访问。这样,线程之间可以高效地交换数据,而不需要经过片外DRAM。

注意:共享内存虽然快,但容量有限(通常只有几十KB)。我在优化一个大型Transformer模型时,就遇到了共享内存不够用的问题。最后不得不把矩阵分块,分批次计算。所以,写GPU代码时,一定要算清楚共享内存的占用,别超了。

最后,咱们用一张图来总结一下AI芯片的数据流架构:

AI芯片数据流架构核心逻辑 片外DRAM 片上缓存 计算阵列 数据复用(权重驻留/输入重用) SIMD/SIMT 单指令多数据/线程 适合矩阵乘、卷积 脉动阵列 数据流水式流动 高吞吐、低带宽需求 近存计算 计算靠近数据 减少数据搬运开销 核心目标:最大化数据复用,最小化片外访问

这张图展示了AI芯片数据流的完整链路。从片外DRAM到片上缓存,再到计算阵列,每一步都在跟“数据搬运”作斗争。而SIMD/SIMT、脉动阵列、近存计算,就是三种主流的战斗策略。

嗯,今天的内容就到这儿。记住一句话:AI芯片的性能,不取决于计算单元有多快,而取决于数据能多快送到计算单元手里。理解了这一点,你就抓住了AI芯片设计的命门。

个人经验:我刚开始做AI芯片时,总喜欢堆计算单元,觉得越多越好。结果发现,计算单元多了,数据根本喂不饱,利用率反而更低。后来我学乖了,先算清楚带宽,再决定计算单元的规模。这个教训,值好几百万流片费呢。

想要更多资料,联系可可