现代图形处理器可以拥有数千个计算核心,而一颗普通的桌面 CPU,可能只有八个、十二个或十六个核心。
一、为什么数千个 GPU 核心不能取代 CPU
乍看之下,这样的比较似乎非常不公平。
如果 GPU 拥有数千个核心,而 CPU 只有十几个核心,那么 GPU 难道不应该比 CPU 强大数千倍吗?
如果 GPU 在人工智能、科学计算、视频处理和游戏领域如此强大,为什么现代计算机仍然需要 CPU?
答案是,GPU 核心与 CPU 核心,是为完全不同类型的工作设计的。
CPU 专门用于处理复杂指令、不可预测的决策、操作系统任务,以及必须以极低延迟完成的工作。
GPU 则专门用于同时执行大量相似的计算。
GPU 无法取代 CPU,因为这两种处理器解决的是不同的问题。
二、什么是 CPU?
CPU 的英文全称是 Central Processing Unit,也就是中央处理器。
CPU 是计算机中最主要的通用处理器。
它负责运行操作系统、启动应用程序、管理文件、处理用户输入、控制硬件设备、处理网络活动,并协调系统中的大部分工作。
CPU 必须能够执行许多不同类型的指令,包括:
- 算术运算
- 逻辑运算
- 分支与条件判断
- 内存读取与写入
- 函数调用
- 系统调用
- 中断处理
- 设备控制操作
CPU 还必须能够在完全不同的任务之间快速切换。
这一刻,它可能正在处理键盘输入。
下一刻,它可能正在运行浏览器、接收网络数据包、解压缩文件、调度另一个程序,或者响应某个硬件中断。
这些工作负载通常是不可预测的。
CPU 可能无法提前知道下一条需要执行的指令是什么、程序会进入哪个分支,或者下一份数据位于内存中的什么位置。
正因为如此,CPU 核心的结构非常复杂。
一颗现代 CPU 核心通常包括:
- 高级分支预测器
- 乱序执行硬件
- 推测执行机制
- 大容量多级缓存
- 复杂的指令解码器
- 多个执行单元
- 硬件预取器
- 精确的中断处理机制
- 内存保护机制
- 虚拟内存支持
所有这些硬件,都是为了让 CPU 尽可能快速地执行单个指令流。
CPU 的主要优化目标是低延迟。
它的目标不只是执行大量计算,而是即使面对复杂、变化和不可预测的指令,也能够快速完成每一项重要任务。
三、什么是 GPU?
【插入第3张英文图片】
GPU 的英文全称是 Graphics Processing Unit,也就是图形处理器。
GPU 最初是为了加速计算机图形而设计的。
渲染一个三维场景,需要进行数量极其庞大的相似计算。
在生成每一帧画面时,计算机可能需要处理:
- 数百万个顶点
- 数百万个像素
- 纹理坐标
- 光照计算
- 颜色数值
- 阴影
- 反射
- 透明效果
- 图像滤镜
这些计算往往具有很高的并行性。
例如,一个像素的颜色,通常可以独立于另一个像素进行计算。
计算机没有必要一个接一个地处理所有像素,而是可以让 GPU 同时处理大量像素。
因此,GPU 设计人员开始在处理器内部放置大量相对简单的算术计算单元。
现代 GPU 的用途早已不再局限于图形。
GPU 还可以加速:
- 人工智能
- 机器学习
- 科学模拟
- 视频编码
- 图像处理
- 加密货币计算
- 工程应用
- 三维渲染
- 数据分析
- 天气建模
但是,GPU 的基本设计思想并没有改变。
GPU 的主要优化目标是吞吐量。
它希望在一段时间内完成数量极其庞大的相似任务,而不是保证每一个单独任务都具有极低的延迟。
四、CPU 核心与 GPU 核心并不等价
【插入第4张英文图片】
“核心”这个词,经常会造成误解。
一个 CPU 核心,并不能直接与一个 GPU 核心进行比较。
现代 CPU 核心是一颗功能强大、基本独立的处理器。
它可以执行复杂的指令流、进行判断、处理中断、运行操作系统代码,并高效处理控制流程不规则的任务。
GPU 核心通常只是一个体积较小的算术执行资源。
根据不同厂商和不同架构,GPU 中的计算资源可能被称为:
- CUDA Core,也就是 CUDA 核心
- Stream Processor,也就是流处理器
- Shader Processor,也就是着色器处理器
- Execution Unit,也就是执行单元
- Vector Lane,也就是向量通道
- Arithmetic Logic Unit,也就是算术逻辑单元
这些名称并不一定代表完全相同的硬件。
即使是同一家厂商生产的不同代 GPU,其计算单元的组织方式也可能不同。
因此,直接比较不同架构 GPU 的核心数量,往往会产生误导。
一颗拥有数千个算术单元的 GPU,并不等于拥有数千颗完整的 CPU。
这些算术单元会被组织到更大的结构之中。
例如,GPU 可能将执行资源组织为:
- 流式多处理器
- 计算单元
- 工作组
- Warp 线程束
- Wavefront 波前
- 线程块
大量 GPU 线程会共享指令控制硬件、缓存、寄存器和调度资源。
这种设计能够节省芯片面积和功耗,使 GPU 可以把更多晶体管用于算术计算。
它所付出的代价是,单个 GPU 线程的独立性远低于 CPU 线程。
五、少量强大核心与数千个简单计算单元
【插入第5张英文图片】
CPU 和 GPU 之间的区别,也可以理解为晶体管资源分配方式的不同。
这些硬件包括:
- 预测程序分支
- 重新排列指令执行顺序
- 降低内存访问延迟
- 处理复杂的数据依赖
- 精确维护程序运行状态
它不会把大部分芯片面积用于加速一两个指令流,而是利用这些面积提供大量并行执行单元。
当同一种操作需要应用到大量数据时,GPU 会表现得非常强大。
假设一个程序需要将一百万个数字分别乘以同一个数值。
CPU 可以利用向量指令和多个核心,让一条指令同时处理若干个数字。
GPU 则可以把这一百万个数字分配给数千个并行线程。
但是,假设一个程序需要完成下面一系列操作:
- 读取配置文件。
- 检查操作系统环境。
- 打开网络连接。
- 等待服务器响应。
- 从多个处理路径中选择一个。
- 更新数据库。
- 处理错误。
- 把结果发送给另一个应用程序。
这个任务包含大量分支、依赖、延迟、系统调用和不可预测事件。
CPU 更适合处理这种工作。
六、延迟与吞吐量
【插入第6张英文图片】
真正重要的是延迟与吞吐量之间的差别。
延迟,是完成一项任务所需要的时间。
吞吐量,是在一段时间内能够完成的工作总量。
CPU 的设计目标,是尽可能降低单项任务的延迟。
GPU 的设计目标,是尽可能提高大量任务的总吞吐量。
我们可以用餐厅来做一个比喻。
CPU 就像一位技术高超的厨师。
他可以制作许多不同的菜肴、调整配方、满足顾客的特殊要求,并解决各种意外问题。
GPU 则更像一条大型食品生产线。
这条生产线专门用来生产数千份完全相同的食品。
生产线每小时可以生产远多于厨师的食品,但它并不一定适合制作一份高度定制的菜肴。
同样,GPU 可以处理极其庞大的相似数据批次。
但是,当任务规模很小、必须顺序执行、难以预测,或者包含大量不同分支时,GPU 可能并不高效。
七、GPU 如何执行数千个线程
【插入第7张英文图片】
GPU 通过同时运行大量轻量级线程,实现很高的吞吐量。
但是,这些线程并不总是完全独立地执行。
许多 GPU 使用一种特殊的执行模型,让一组线程同时对不同数据执行相同的指令。
英伟达通常把这种模型称为 SIMT。
SIMT 的英文全称是 Single Instruction, Multiple Threads,也就是单指令、多线程。
一组线程通常被称为一个 Warp,也就是线程束。
同一个 Warp 中的线程会一起向前执行指令。
AMD 使用的相关概念,通常被称为 Wavefront,也就是波前。
假设三十二个 GPU 线程正在处理三十二个像素。
这三十二个线程可以同时执行一条计算亮度的指令。
每个线程执行相同的操作,但是使用不同像素的数据。
这种方式非常高效。
但是,如果同一组线程进入不同的程序分支,问题就会出现。
例如:
|
1 2 3 4 5 6 7 8 9 |
if (pixel_brightness > threshold) { make_pixel_white(); } else { make_pixel_black(); } |
一部分线程可能进入第一个分支,把像素变成白色。
另一部分线程可能进入第二个分支,把像素变成黑色。
由于这些线程共享执行控制硬件,GPU 可能需要分别执行两个分支。
在执行其中一个分支时,不属于该分支的线程会暂时被关闭。
然后 GPU 再执行另一个分支。
这种现象被称为分支发散。
分支发散会降低 GPU 的效率,因为部分执行通道会处于空闲状态。
CPU 核心通常更擅长处理复杂而不可预测的程序分支。
八、为什么 CPU 仍然控制计算机
【插入第8张英文图片】
CPU 仍然是计算机的主要处理器,因为计算机需要完成的工作远远不只是算术运算。
- 调度进程
- 管理虚拟内存
- 处理中断
- 控制存储设备
- 处理网络通信
- 执行安全权限
- 运行设备驱动程序
- 管理文件系统
- 响应用户输入
- 协调应用程序
这些工作通常计算量并不大,但必须立即完成。
它们还包含大量判断和前后依赖。
例如,当你打开一个文件时,计算机可能需要:
- 解释文件路径。
- 检查访问权限。
- 搜索文件系统元数据。
- 找到数据在存储设备上的位置。
- 分配内存。
- 请求设备驱动程序读取数据。
- 在读取完成时处理中断。
- 把数据复制给应用程序。
- 报告可能出现的错误。
这并不是一批完全相同的算术运算。
它是一连串不同的操作,其中许多操作必须等待前一个操作完成。
CPU 正是为这种工作设计的。
九、GPU 通常依赖 CPU
【插入第9张英文图片】
在许多计算机中,GPU 的角色是加速器,而不是一台完全独立的计算机。
一个简化的 GPU 工作流程如下:
- CPU 启动应用程序。
- 应用程序在系统内存中准备数据。
- CPU 分配 GPU 资源。
- 数据被传输或映射到 GPU 可以访问的内存。
- CPU 向 GPU 提交命令。
- GPU 执行数千个并行线程。
- GPU 保存计算结果。
- CPU 使用、显示、保存或传输这些结果。
即使 GPU 完成了大部分计算,CPU 仍然负责管理应用程序、操作系统、输入输出、文件、网络和整个程序流程。
以游戏为例,CPU 可能负责:
- 游戏逻辑
- 游戏角色的人工智能
- 物理计算协调
- 输入处理
- 音频
- 网络通信
- 场景准备
- 提交绘制命令
GPU 则负责大量图形工作,包括:
- 顶点处理
- 光栅化
- 纹理采样
- 像素着色
- 光照
- 光线追踪
- 图像重建
最终的游戏体验依赖两种处理器共同完成。
如果一颗强大的 GPU 搭配一颗速度很慢的 CPU,就可能出现 CPU 瓶颈。
GPU 可能无法获得足够的工作,只能部分闲置,因为 CPU 无法足够快速地准备和提交任务。
十、为什么不是所有程序都能使用数千个 GPU 核心
【插入第10张英文图片】
要高效使用 GPU,一个问题通常必须包含足够多可以并行执行的工作。
有些任务天生适合并行处理。
另一些任务则必须按顺序执行。
考虑下面这个简单的依赖关系:
- 步骤 B 需要步骤 A 的结果。
- 步骤 C 需要步骤 B 的结果。
- 步骤 D 需要步骤 C 的结果。
这些步骤无法同时执行。
无论 GPU 拥有多少核心,在步骤 C 完成之前,步骤 D 都不能开始。
这就是核心数量增加并不会自动让所有程序变快的原因之一。
一个程序可能同时包含并行部分和顺序部分。
并行部分可以通过 GPU 加速,但顺序部分仍然必须按顺序执行。
这个限制与阿姆达尔定律密切相关。
阿姆达尔定律说明,一个程序能够获得的最大加速效果,会受到程序中无法并行部分的限制。
如果一个程序只有一半可以被加速,那么即使把这一半的运行时间降到接近零,整个程序的速度最多也只能提高到原来的两倍。
真实程序中还存在各种额外开销。
在 GPU 开始进行有效计算之前,系统可能需要:
对于一个很小的任务,这些开销甚至可能比直接在 CPU 上运行任务所需的时间更长。
十一、内存架构同样重要
【插入第11张英文图片】
CPU 通常拥有多个层级的低延迟缓存。
一个常见的 CPU 内存层次结构包括:
- 一级缓存,也就是 L1 Cache
- 二级缓存,也就是 L2 Cache
- 多个核心共享的三级缓存,也就是 L3 Cache
- 主系统内存
CPU 使用复杂的缓存逻辑和数据预取技术,尽可能减少等待数据的时间。
GPU 通常拥有更高的内存带宽。
高端 GPU 可能使用专门设计的显存系统,每秒可以传输极其庞大的数据量。
这种能力对于图形、人工智能和科学计算非常重要,因为这些工作经常需要处理大型数组、纹理、矩阵和张量。
但是,高带宽并不等于低延迟。
GPU 可以通过在线程组之间切换,隐藏内存访问延迟。
当一组线程正在等待数据时,GPU 可以让另一组线程使用执行单元。
当 GPU 中有数千个线程可以运行时,这种方式非常有效。
CPU 的设计目标,则是降低少量活动线程实际感受到的延迟。
再一次,CPU 关注的是低延迟,而 GPU 关注的是高吞吐量。
十二、独立 GPU 与数据传输开销
【插入第12张英文图片】
独立 GPU 通常拥有自己的视频内存,也就是显存。
数据可能需要通过 PCI Express 等互连总线,在这两个内存空间之间移动。
这种数据传输可能成为性能瓶颈。
假设一项 GPU 计算只需要一毫秒,但传输输入和输出数据需要五毫秒。
那么整个操作至少需要六毫秒。
在这种情况下,GPU 的算术性能并不是唯一重要的因素。
程序设计人员还必须考虑:
- 数据传输量
- 数据传输频率
- 内存布局
- 同步操作
- GPU 内核启动开销
- 缓存行为
- 数据重复使用
高效的 GPU 程序,会尽量让数据长时间保留在 GPU 附近,并在一次数据传输后完成足够多的计算,从而抵消传输开销。
十三、集成 GPU 改变了内存模型
【插入第13张英文图片】
集成 GPU 位于与 CPU 相同的处理器封装或同一颗芯片之中。
这样可以减少在两个独立内存系统之间复制数据的需求。
现代片上系统,也就是 SoC,可能提供更加紧密的集成。
CPU 核心、GPU 计算单元和其他加速器,可以访问共享内存架构。
但是,共享内存并不会让 CPU 与 GPU 变成相同的处理器。
它们仍然拥有不同的执行硬件,并继续针对不同的工作负载进行优化。
共享内存的主要优势,是让 CPU 与 GPU 之间的通信速度更快、能源效率更高。
这对于以下设备尤其有用:
- 笔记本电脑
- 智能手机
- 平板电脑
- 小型计算机
- 游戏主机
- 高能效工作站
十四、为什么 GPU 特别适合人工智能
【插入第14张英文图片】
一个神经网络可能需要执行数量极其庞大的乘加运算。
这些计算具有很高的并行性。
例如,矩阵中的许多元素可以相互独立地进行计算。
GPU 可以把这些工作分配给数千个执行单元。
现代 GPU 还可能包含专门用于人工智能计算的硬件,例如张量计算单元。
这些单元可以加速机器学习中经常使用的低精度计算。
但是,这并不意味着 CPU 变得不再必要。
CPU 仍然需要负责:
在人工智能推理过程中,GPU 可能完成大部分矩阵运算,但 CPU 仍然负责运行外围应用程序。
在人工智能训练过程中,CPU 还可能负责数据加载、数据预处理、存储、网络通信,以及多个 GPU 之间的协调。
十五、为什么操作系统不能简单地运行在 GPU 上
【插入第15张英文图片】
一个通用操作系统需要处理:
- 中断
- 异常
- 特权级别
- 虚拟内存
- 进程隔离
- 精确的控制流程
- 设备管理
- 上下文切换
- 低延迟响应
- 复杂的系统调用
GPU 线程主要用于执行并行数值计算。
它们通常不是为了独立运行完整的桌面应用程序、直接响应每一个硬件中断,或者管理传统操作系统而设计的。
部分现代 GPU 已经拥有越来越强的可编程能力。
一些 GPU 还包括高级调度、内存管理和虚拟化功能。
CPU 仍然是通用控制处理器。
GPU 仍然是高吞吐量计算加速器。
十六、通常更适合 CPU 的工作负载
【插入第16张英文图片】
对于具备以下特征的工作负载,CPU 通常是更好的选择:
- 复杂分支
- 顺序依赖
- 小型数据集
- 低延迟要求
- 不规则内存访问
- 频繁的系统调用
- 大量操作系统交互
- 复杂的程序逻辑
- 许多相互无关的任务
- 有限的并行性
典型例子包括:
其中一些应用程序可以使用 GPU 加速特定部分,但其主要控制流程通常仍然运行在 CPU 上。
十七、通常更适合 GPU 的工作负载
【插入第17张英文图片】
当工作负载具备以下特点时,GPU 通常是更好的选择:
- 拥有大量可并行处理的数据
- 需要重复执行算术操作
- 对大量元素应用相似指令
- 需要很高的内存带宽
- 拥有足够多的工作,可以抵消调度开销
- 不同线程之间的通信较少
典型例子包括:
- 三维图形
- 神经网络训练
- 神经网络推理
- 图像滤波
- 视频处理
- 科学模拟
- 矩阵乘法
- 分子建模
- 金融建模
- 图像渲染
- 大规模数据处理
最适合 GPU 的工作,可以被划分为数千个甚至数百万个相似任务。
十八、CPU 与 GPU 对比
【插入第18张英文图片】
| 对比项目 | CPU | GPU |
|---|---|---|
| 主要目标 | 低延迟 | 高吞吐量 |
| 核心设计 | 少量强大的核心 | 大量较简单的执行单元 |
| 控制流程 | 擅长处理复杂分支 | 最适合相似的指令路径 |
| 并行能力 | 有限到中等 | 大规模并行 |
| 缓存设计 | 大容量、复杂的缓存 | 支持大量活动线程 |
| 操作系统 | 运行主要操作系统 | 通常作为加速器 |
| 最适合的任务 | 通用和顺序任务 | 大规模并行数值计算 |
| 内存重点 | 低延迟访问 | 高带宽 |
| 任务切换 | 非常灵活 | 处理大型批量任务时效率最高 |
| 独立性 | 可以运行完整应用程序 | 通常依赖 CPU 协调 |
现代 CPU 也包含向量计算单元和越来越多的核心。
现代 GPU 也包含缓存、调度器、控制处理器,以及越来越复杂的执行硬件。
但是,它们最主要的设计目标仍然不同。
十九、GPU 将来能取代 CPU 吗?
【插入第19张英文图片】
未来的 GPU 将会变得越来越强大。
它们可能获得:
- 更好的任务调度
- 更灵活的控制流程
- 更先进的内存系统
- 更强的虚拟化功能
- 更加独立的执行能力
- 与 CPU 更紧密的集成
- 更好的通用程序支持
与此同时,CPU 也正在变得更加并行。
现代 CPU 可能包括:
未来不太可能出现一种通用处理器,能够取代所有其他处理器。
计算系统正在变得越来越异构。
一个现代系统可能同时包括:
每一种处理器都负责自己最擅长的工作。
CPU 则负责协调这些组件,并运行通用软件环境。
二十、为什么核心越多不一定性能越高
【插入第20张英文图片】
处理器性能不能只通过核心数量衡量。
其他重要因素还包括:
- 时钟频率
- 每个时钟周期能够完成的指令数量
- 内存延迟
- 内存带宽
- 缓存容量
- 缓存效率
- 分支预测准确率
- 指令级并行能力
- 软件优化程度
- 散热限制
- 功耗
- 数据传输开销
- 工作负载的并行程度
一个为单个 CPU 线程设计的程序,不会自动使用十六个 CPU 核心。
同样,一个为 CPU 编写的程序,也不会自动使用数千个 GPU 执行单元。
软件本身必须能够提供可以并行执行的工作。
开发人员可能需要重新设计算法、仔细组织内存、减少分支发散、降低数据传输次数,并把工作划分为适合 GPU 的操作。
只有软件能够充分利用硬件时,硬件能力才有实际价值。
二十一、简单示例:渲染一帧游戏画面
【插入第21张英文图片】
现代电子游戏很好地展示了 CPU 与 GPU 如何协同工作。
CPU 可能负责:
- 读取键盘、鼠标或游戏控制器输入
- 更新玩家和物体的位置
- 运行游戏规则和角色行为
- 处理网络通信
- 准备游戏场景
- 决定哪些物体应该显示
- 提交渲染命令
接下来,GPU 可能负责:
- 转换物体顶点
- 处理几何图形
- 对三角形进行光栅化
- 采样纹理
- 计算光照
- 应用着色器
- 执行光线追踪
- 生成最终图像
CPU 决定游戏中正在发生什么。
GPU 计算游戏画面应该如何显示。
任何一种处理器单独工作,都无法高效提供完整的游戏体验。
二十二、简单示例:运行一个人工智能应用
【插入第22张英文图片】
假设一台本地计算机正在运行一个人工智能聊天程序。
CPU 可能负责:
- 启动应用程序
- 加载配置文件
- 读取用户输入的提示词
- 对文本进行分词
- 分配内存
- 加载模型数据
- 提交矩阵运算
- 管理输出生成
- 显示结果
- 保存对话记录
GPU 完成了大量数值计算工作,但 CPU 仍然负责管理应用程序,并协调完整的处理过程。
最终的人工智能系统,是 CPU 与 GPU 共同合作的结果。
二十三、数千个 GPU 核心的真正含义
【插入第23张英文图片】
当 GPU 的规格表中列出数千个核心时,这并不意味着 GPU 内部拥有数千个功能完整、相当于 CPU 核心的处理器。
它真正的含义是,GPU 内部拥有数量极其庞大的算术计算资源。
这些资源经过专门设计,可以共同处理并行工作负载。
当满足以下条件时,这些计算资源可以提供非常强大的性能:
- 问题可以被划分成大量相似任务
- 系统拥有足够多的线程
- 数据排列方式适合并行访问
- 分支发散较少
- 内存带宽得到有效利用
- 线程之间的通信开销受到控制
如果这些条件无法满足,许多 GPU 核心可能会处于空闲状态,或者以很低的效率运行。
在这种情况下,数量较少但功能复杂的 CPU 核心,反而可能更快地完成任务。
二十四、总结:CPU 提供控制,GPU 提供并行力量
【插入第24张英文图片】
CPU 和 GPU 都是处理器,但它们围绕不同的设计重点构建。
CPU 针对灵活性、复杂控制流程、低延迟和通用计算进行了优化。
GPU 针对大规模并行、高算术吞吐量和高带宽数据处理进行了优化。
GPU 可以包含数千个计算单元,是因为每个计算单元都更小,并且与周围的计算单元共享更多控制硬件。
CPU 的核心数量较少,是因为每一个核心都必须能够独立处理复杂而不可预测的指令流。
CPU 负责运行系统、进行决策、处理不规则任务,并协调各种应用程序。
GPU 负责加速大规模的相似计算。
现代计算并不是一场必须由一种处理器击败另一种处理器的竞争。
它们是一种协作关系。
CPU 提供控制能力。
GPU 提供并行计算力量。
当 CPU 与 GPU 共同工作时,计算机能够完成比任何一种处理器单独工作时更加复杂、更加强大的任务。


