gpu和tpu都属于专用芯片,而cpu属于通用芯片
x86 cpu
| 实模式寄存器 | 保护模式寄存器 | 长模式寄存器 | 描述 |
|---|---|---|---|
| AX、BX、CX、DX、DI、SI、BP | EAX、EBX、ECX、EDX、EDI、ESI、EBP | RAX、RBX、RCX、RDX、RDI、RSI、RBP、R8 - R15 | 通用寄存器,里面可以存放数据、地址、参与运算 |
| IP | EIP | RIP | 程序指针寄存器,始终指向下一条指令的地址 |
| SP | ESP | RSP | 栈指针寄存器,始终指向当前栈顶 |
| CS、DS、ES、SS | 同实模式,新增FS、GS | 同实模式,新增FS、GS | 16位段寄存器,里面存放一个内存段的基地址或者描述符索引 |
| FLAGS | EFLAGS | RFLAGS | CPU标志寄存器,里面存放CPU执行运算指令产生的状态位 |
| 无 | CR0、CR1、CR2、CR3 | CR0还是32位,CR1、CR2、CR3都是64位 | CPU控制寄存器,控制CPU的功能控制特性,如开启保护模式、长模式等 |
- x86 cpu的位数越来越高,从16位到32到64,每次进步都尽量的去兼容之前的cpu架构,所以:
- 16位时寻址能力不足,要借助额外的段寄存器进行1M空间的寻址; 32位时,每个程序都有自己独立的4G寻址空间,操作系统用低位的1G-2G,其余留给用户程序;64位时,暂时就遇不到寻址能力不足的事情了
- 前一代的寄存器尽量保留,不够用就扩展新的
- 寄存器的长度升级后,其低位可以兼容上一代的寄存器
- CPU同时在安全性上也要提升,从只有实模式,到了32位的保护模式,而64位的长模式在安全方面与32位并没有本质区别。
- 从实模式到保护模式,访问内存时,需要访问的地址变大了,需要控制的内容变多了,于是引入了段描述符,所有的段描述符组成了描述符表,包括唯一的全局描述符GDT和多个局部描述符LDT。
- BIOS引导后,系统直接进入最简单、特权最大的实模式;而后告知CPU,切换到保护模式,并运行在ring0。后续的用户进程,一般就在ring3,想执行特权指令要通过操作系统来执行。
gpu的指令集不稳定,不向下兼容,所以需要cuda这类语言来处理这种变化
您的理解有一部分是对的,但不完全准确。更精确的说法是:
CPU的指令集架构相对稳定,而GPU的指令集/微架构在不同代际和产品线上变化更快、更剧烈。
我们来具体分析一下:
1. 关于CPU指令集“固定”
- 架构层面稳定:在消费级和服务器市场,x86和ARM是两大主流指令集架构。一旦确立,它们会保持长期的向后兼容性。例如,今天的Intel/AMD CPU依然能运行几十年前为x86编写的程序。这种稳定性是生态系统的基石。
- 并非一成不变:CPU指令集也在不断扩展,例如x86的MMX, SSE, AVX, 以及ARM的NEON, SVE等扩展指令集,都是为了加速特定类型的计算。但核心的整数、浮点、控制流等基础指令集非常稳定。
2. 关于GPU指令集“变动”
您的观察非常敏锐。英伟达GPU的指令集在不同架构(Architecture)之间存在显著差异,甚至在同一架构的不同产品间也有调整。
- 架构代际差异巨大:这是最主要的变化点。例如,Tesla架构、Fermi架构、Kepler、Maxwell、Pascal、Volta、Turing、Ampere、Hopper、Blackwell,每一代新架构的底层指令集、核心设计、内存模型、硬件调度等都可能发生重大改变。为上一代架构优化的汇编代码,在下一代上通常无法直接运行。
- 编程模型统一:为了应对这种底层硬件的快速变化,并方便开发者,英伟达提供了CUDA这一统一的并行计算平台和编程模型。开发者主要使用高级语言(如CUDA C++)编程,由英伟达的编译器(nvcc)将代码转换成适用于当前GPU架构的PTX和最终的SASS指令。
- PTX:一种中间汇编语言,相对稳定。它为不同架构的GPU提供了一个通用的“目标”。
- SASS:这才是真正的、与特定硬件架构绑定的机器指令集。它才是您说的那个“变动”的部分。不同架构的GPU,其SASS指令集是不同的。英伟达的驱动程序会在运行时将PTX编译成对应硬件的SASS。
总结一下:
- CPU:像一个长期稳定的、不断扩建的“基础语言体系”。核心语法不变,但会不断增加一些高级词汇和修辞手法。
- GPU:它的硬件底层(SASS指令集)像一个快速迭代的“硬件方言”,每代都变。但英伟达通过CUDA编程模型和PTX中间语言,构建了一个统一的、相对稳定的“官方通用语”给开发者使用,从而屏蔽了底层硬件的复杂性。
所以,更准确的说法是: CPU的指令集架构(ISA)在生态压力下保持高度稳定和兼容;而GPU的底层硬件指令集(SASS)随着架构迭代而变化迅速,但其上层的编程模型(CUDA)通过中间层(PTX)提供了稳定性,使得开发者无需直接面对频繁变动的底层指令。
cpu有指令集和对应的汇编语言,gpu有这些么
有,而且更复杂。 这是理解 GPU 编程模型的关键。GPU 拥有自己完整的指令集和对应的“汇编语言”,但这些通常不直接暴露给普通程序员,而是被 CUDA/ROCm 这样的高级编程模型封装起来了。
可以说,CUDA C++/HIP 之于 GPU,就类似于 C/C++ 之于 CPU。它们都是高级语言,会被编译成底层的机器指令。
1. GPU 的指令集与“汇编语言”
-
NVIDIA GPU:PTX 和 SASS
- PTX:并行线程执行虚拟指令集。这是 NVIDIA 定义的中间汇编语言,是稳定、公开的。当你用
nvcc编译 CUDA C++ 代码时,会先编译成 PTX。PTX 是跨 NVIDIA GPU 架构的,类似 Java 字节码。它比 CUDA C++ 低级,但还不是最终硬件指令。 - SASS:流处理器汇编。这是 NVIDIA GPU 真正的原生机器码,是闭源、不公开、且因 GPU 架构代际而异的。PTX 代码在 GPU 驱动加载时,会被即时编译成对应具体 GPU 型号的 SASS 代码。普通开发者几乎不接触 SASS,只有 NVIDIA 内部工具或高级逆向工程会分析它。
- PTX:并行线程执行虚拟指令集。这是 NVIDIA 定义的中间汇编语言,是稳定、公开的。当你用
-
AMD GPU:GCN/RDNA ISA 和 AMDGCN
- AMD 公开了其 GCN 和 RDNA 架构的指令集参考手册。其对应的汇编语言通常被称为 AMDGCN 汇编。
- 类似于 NVIDIA 的流程,ROCm 的编译器(如
clang)会将 HIP 代码编译成 AMDGPU 的中间表示,最终生成对应硬件的机器码。
所以,GPU 指令集是存在的,但被厂商的驱动和编译器工具链严密地封装和管理着。
2. 与 CPU 生态的惊人对比
| 层面 | CPU 世界 | GPU 世界 (以 NVIDIA 为例) | 说明 |
|---|---|---|---|
| 高级编程语言 | C, C++, Rust, Go 等 | CUDA C++ (NVIDIA), HIP (AMD, 语法类似 CUDA) | 都是高级语言,用于编写业务逻辑和并行算法。 |
| 稳定/公开的中间表示/汇编 | 汇编语言 (x86-64 ASM, ARM ASM) | PTX | CPU汇编是直接映射到机器指令的低级语言。PTX 是虚拟指令集,更稳定,是公开的编译目标。 |
| 私有/最终的机器码 | 机器码 (由 CPU 微架构直接执行) | SASS | CPU 机器码在手册中定义。SASS 是 NVIDIA 不公开的、硬件相关的最终二进制格式。 |
| “操作系统”角色 | 操作系统内核 | GPU 驱动 | OS 管理 CPU 资源调度、内存、进程。GPU 驱动管理 GPU 资源、编译 PTX 到 SASS、任务排队、内存传输。 |
| 编译流程 | C源码 -> 编译器 -> 目标文件 -> 链接器 -> 可执行文件 (x86/ARM机器码) |
CUDA源码 (.cu) -> nvcc -> PTX + x86代码 -> GPU驱动 (JIT编译PTX->SASS) -> 在GPU执行 |
GPU 增加了关键的 JIT 编译 步骤,由驱动完成。 |
3. 为什么 GPU 的“汇编”不常被直接使用?
- 极度复杂性:GPU 是海量核心(SIMT 模型),编程时思考的单位是网格、线程块、线程,还要考虑共享内存、同步、warp 调度等。用 PTX 这种低级语言手动管理数万个线程的协同,是极其困难且容易出错的。CUDA C++ 帮你抽象了这些。
- 性能优化主要在高层:GPU 性能的瓶颈往往在于内存访问模式、线程块配置、共享内存使用等。这些在 CUDA C++ 的模型层面就能进行很好的优化。直接写 PTX 带来的性能提升,远小于在高层模型上优化带来的收益,且代价巨大。
- 硬件的 JIT 优化:GPU 驱动在将 PTX 编译为 SASS 时,会做很多针对特定 GPU 型号的激进优化(如指令调度、寄存器分配)。手工写的 SASS 很难超越优化器的结果。
- 可移植性:写 CUDA C++ 可以保证代码在未来的 NVIDIA GPU 上运行(通过 PTX JIT)。如果直接写某一代 GPU 的 SASS,代码将完全绑定在该硬件上。
4. 何时会接触 GPU 的“汇编”?
- 编译器开发者:开发 CUDA/ROCm 编译器、或像 LLVM 这样的编译器后端时,需要生成 PTX 或 AMDGCN 代码。
- 性能极客/库开发者:在开发极度追求性能的数学库时,可能会内联 PTX 汇编片段以实现某些特定的硬件指令或微优化。
- 逆向工程与安全研究:分析恶意软件或进行漏洞研究时,可能会反汇编 GPU 代码。
- 高级调试:使用像
nvdisasm这样的工具来反汇编 GPU 内核二进制码,以进行底层调试。
类比总结
想象你要指挥一场由数万名士兵(GPU 线程)参与的协同作战:
- CUDA C++/HIP:你作为将军,用高级军事术语发布命令:“第一兵团,以楔形阵型,占领A区域。第二兵团,侧翼掩护。” 这抽象、高效。
- PTX/AMDGCN 汇编:你降级为传令兵,需要将将军的命令,翻译成对每个连、排、班的具体行进路线、开火时机、弹药补给等详细指令集。工作量剧增,但仍有结构。
- SASS/机器码:这相当于每个士兵神经元接收到的生物电信号。这是命令的最终物理形式,人类几乎无法直接编写和阅读。
CPU 生态:由于士兵(CPU核心)数量少、能力全面,你可以直接对每个士兵下达稍微详细一点的指令(汇编),虽然累,但可行。因此汇编语言在 CPU 世界更常见。
GPU 生态:由于士兵(流处理器核心)数量极多、能力单一,你绝对不能直接指挥每个人。必须依赖一套强大的指挥系统(CUDA/ROCm 运行时+驱动),把你的高层战略意图(CUDA C++ 核函数)自动分解、优化、并转化成数万个低层神经信号(SASS)发送给每个士兵。这个“自动转化”的过程,就是 GPU 编程模型的核心价值。
结论:GPU 不仅有指令集和汇编,而且其软硬件分工更加明确——高级模型负责可编程性和生产力,底层驱动和硬件负责将高级意图转化为海量并行线程的高效执行。开发者被鼓励工作在高级模型层,这正是 CUDA 和 ROCm 存在的意义。
为何gpu会有cuda或者ROCm呢?而cpu却没有这样的概念
这是一个触及计算机体系结构根本差异的精彩问题。CPU 和 GPU 设计哲学和应用模式的不同,导致了编程模型和生态的巨大分野。
简单说:CPU 是“通用、串行优化”的指挥官,有统一的标准接口;GPU 是“专用、并行计算”的大兵团,需要专属的“动员令”和“后勤系统”。
下面从几个核心维度拆解:
1. 设计目标与市场生态的根本不同
-
CPU:通用中央处理器
- 目标:擅长处理复杂、不可预测、控制密集型的任务。比如运行操作系统、处理逻辑判断、响应中断、执行单线程复杂算法。它的核心是低延迟和强通用性。
- 生态:经过几十年发展,形成了以 x86 和 ARM 指令集架构为核心的两大成熟、高度标准化的生态。操作系统、编译器、应用软件都基于这些标准的 ISA 构建。应用程序通过操作系统,使用标准系统调用和驱动模型来间接使用 CPU,无需直接“命令”CPU核心。
-
GPU:图形处理器 -> 并行计算加速器
- 起源:最初专为高度并行、可预测、计算密集型的图形渲染(处理数百万个像素和顶点)而设计。
- 演变:人们发现其大规模并行架构非常适合科学计算、AI等。但 GPU 的硬件架构(数千个简化核心、复杂的内存层次、SIMT执行模型)与 CPU 截然不同,没有像 x86/ARM 那样的行业通用指令集标准。
- 生态:GPU 市场被 NVIDIA 和 AMD 两家巨头主导,它们各自为政,硬件设计差异大。为了让开发者能用起来,它们必须自上而下地提供一套完整的软件栈,这就是 CUDA 和 ROCm。这套东西不仅包括编程语言,更是从驱动、编译器、运行时到数学库的完整计算平台。
关键比喻:买房子(CPU生态) vs 租用特种工厂(GPU生态)。
- CPU(房子):地基和结构(ISA标准)是统一的,你通过物业(操作系统)来使用,室内装修(应用程序)有大量通用方案。
- GPU(特种工厂):每家公司(NVIDIA/AMD)的工厂布局、生产线、机器操作手册都完全不同。你必须使用该厂提供的全套“操作培训、工具和物流系统”(CUDA/ROCm)才能让工厂为你生产。
2. 编程模型与“进入”方式的差异
-
CPU:你是“住户”,通过“物业”下达指令
- 标准入口:你用 C/C++/Rust 等语言写程序,调用标准库。编译器将其编译成 x86/ARM 指令。操作系统负责把你的程序加载到内存,调度到 CPU 核心上执行。
- 无需特定 SDK:你不需要安装“Intel C++ 编译器套装”或“AMD CPU 开发套件”来写普通程序。CPU 对程序员是透明的计算资源,由操作系统管理。
-
GPU:你是“工厂调度员”,需要“专属调度系统”
- 非标准入口:GPU 是一个独立的、与 CPU 异构的加速设备。CPU(主机)不能直接对它下指令。必须通过特定的驱动程序和API 来“投喂”数据和“启动”计算任务。
- 专用 SDK 是必须的:CUDA/ROCm 就是这套“调度系统”。它们定义了:
- 如何与 GPU 通信:驱动和运行时 API。
- 如何在 GPU 上编程:CUDA C++ 或 HIP 语言,让你能编写在 GPU 上万个线程上运行的核函数。
- 如何利用 GPU 硬件功能:封装了张量核心、共享内存、 warp 操作的库和内置函数。
- 没有这套系统,GPU 对你就是一块无法进行通用计算的“黑盒子”。
3. 硬件架构与编程复杂性的差异
- CPU 相对“简单”:核心数少(几到几百),每个核心功能强大,能独立处理复杂任务。内存系统统一。编程模型(多线程)与硬件映射相对直接。
- GPU 极度复杂:核心数极多(几千到上万),但核心简单,以线程束为单位执行相同指令。内存层次多(全局、共享、本地、常量、纹理),需要显式管理以获取性能。这种复杂性必须被软件栈有效抽象和管理。
- CUDA/ROCm 的核心价值之一就是管理这种复杂性:它们提供了 线程层次模型、内存空间标识符、同步原语 等,让程序员能在如此复杂的硬件上组织计算。没有它们,直接操作 GPU 硬件寄存器将是噩梦。
4. 历史与商业原因
- 标准化的缺失:CPU 领域,x86 和 ARM 通过长期的竞争与合作,形成了事实上的软件标准。而 GPU 在通用计算领域是“新大陆”,NVIDIA 凭借 CUDA 先行一步,建立了强大的生态壁垒。AMD 作为追赶者,推出了兼容 CUDA 概念的 ROCm,但无法统一市场。双方都没有动力向对方开放底层硬件接口。
- 垂直整合的商业策略:对于 NVIDIA/AMD,CUDA/ROCm 不仅仅是技术工具,更是锁定用户、构建护城河的核心战略资产。一旦你的代码和生态建立在 CUDA 上,迁移到其他硬件成本极高。这促使它们投入巨资完善自己的软件栈,而不是合作建立开放标准。
类比总结
| 维度 | CPU 生态 | GPU 生态 |
|---|---|---|
| 角色 | 通用指挥官 (擅统筹,做决策) | 特种兵军团 (擅大规模重复作业) |
| 接口 | 标准化军营 (x86/ARM指令集),有通用指挥链 (操作系统)。 | 两家不同的特种装备供应商 (NVIDIA/AMD),各有自己的独家装备操作手册和后勤体系 (CUDA/ROCm)。 |
| 使用方式 | 你作为将军,向军营下达任务目标 (可执行程序),军营内部自行安排士兵 (CPU核心) 完成。 | 你需要先学习其中一家的操作手册,然后用其专用语言编写详细的、面向成千上万个特种兵 (流处理器) 的协同作战指令 (核函数),并通过其专用后勤通道 (驱动) 下达。 |
| 目标 | 灵活应对各种战场 (任务)。 | 为了极致完成特定的大规模作战任务 (并行计算)。 |
所以,为什么 CPU 没有 CUDA?
因为 CPU 的“通用军营”及其“标准指挥链”(操作系统+指令集)已经高度成熟和标准化。你不需要为 Intel 或 AMD 的 CPU 单独学习一套编程模型,操作系统已经帮你搞定了一切。
为什么 GPU 必须有 CUDA/ROCm?
因为 GPU 是功能强大但结构独特的“特种工厂/军团”,没有行业通用的“操作标准”。硬件厂商必须提供一整套专属的“操作和指挥系统”,才能让开发者用起来。这套系统就是 CUDA 和 ROCm,它们是连接开发者的高级意图与GPU底层复杂硬件的不可或缺的桥梁和翻译官。
未来的趋势:像 SYCL、OpenMP 等开放标准,以及 Mojo 这类新语言,正试图成为能对接不同 GPU 后端的“通用翻译层”,但它们的底层仍然需要调用 CUDA 或 ROCm 来完成最终到硬件的对接。短期内,CUDA/ROCm 作为硬件厂商主导的底层平台,其地位难以撼动。
risc-v 的指令集是可以变动的,那是不是可以同时充当通用芯片,和专用芯片了。
是的,RISC-V 指令集架构的“可扩展性”是其核心设计特点之一,这使它能够非常灵活地在“通用”与“专用”之间找到平衡点,或者说,能够同时承担这两种角色。
具体来说,这主要得益于以下几个机制:
1. 模块化的基础指令集
RISC-V 定义了一个最小的、稳定的基础整数指令集,比如 RV32I 或 RV64I。这个“I”子集提供了CPU运行操作系统和基本软件所需的最少指令。所有兼容 RISC-V 的处理器都必须实现它,这确保了软件基础的通用性。
2. 标准扩展指令集
在基础指令集之上,RISC-V 定义了许多可选的标准扩展,处理器设计者可以像搭积木一样选择添加:
- M 扩展: 整数乘除法。几乎所有通用处理器都会加上。
- A 扩展: 原子操作,支持多核/多线程,通用计算必备。
- F/D 扩展: 单/双精度浮点运算,用于科学计算、图形等。
- C 扩展: 压缩指令,减少代码体积,提高效率。
一个追求通用性的芯片(如用于物联网、嵌入式Linux的处理器)通常会选择“RV64GC”这样的配置,它包含了大部分标准扩展,性能均衡,能运行丰富的软件栈。
3. 自定义扩展指令集
这是实现“专用芯片”能力的关键。RISC-V 预留了大量的自定义操作码空间,允许芯片设计者根据自己的特定需求,定义全新的指令。
- 例子1:AI加速: 一家公司可以设计一组专用的向量/矩阵运算指令,并添加到自己的RISC-V核心中,使其在运行神经网络推理时效率远超通用CPU,这就是一个“专用AI加速芯片”,但其核心仍是RISC-V,能运行控制代码。
- 例子2:网络处理: 可以为数据包校验、加密解密、路由查找等设计专用指令,打造高性能网络处理器。
- 例子3:存储控制器: 为闪存管理、数据压缩/去重设计指令。
这意味着,你可以在一个RISC-V核心上,既有通用的“大脑”(基础指令集+标准扩展),又有为特定任务优化的“专用肌肉”(自定义扩展)。
如何同时充当通用和专用芯片?
这种结合通常通过两种方式实现:
-
异构计算(Chip-Level):
- 在一个SoC芯片内部,放置几个高性能的通用RISC-V核心(运行操作系统和主流应用),再搭配几个针对特定任务优化的专用RISC-V核心(如AI、DSP、图像处理)。
- 通用核心负责控制、调度和通用计算,专用核心在需要时被调用,处理高强度专项任务。这类似ARM的“大小核”+“GPU/NPU”架构,但所有核心的指令集基础都统一为RISC-V,设计自由度更高。
-
可配置核心(Core-Level):
- 设计一个可配置的RISC-V处理器核心,客户可以根据自己的应用场景,选择添加哪些标准扩展,并集成自己的自定义扩展指令。
- 例如,一个做视频监控的公司,可以定制一个带有强大图像处理专用指令的RISC-V核心。这个核心既能流畅运行Linux系统来处理网络、存储等通用任务,又能在执行视频编解码、目标检测等算法时,通过专用指令获得极致的性能和能效。
优势和挑战
- 优势:
- 灵活性: 真正实现“软硬件协同设计”,为特定领域(DSA)优化。
- 效率: 专用指令能极大提升性能、降低功耗。
- 控制力: 公司拥有从指令集到微架构的完整自主权,无需支付高额架构授权费。
- 挑战:
- 软件生态: 自定义扩展需要配套的编译器、工具链、库函数乃至操作系统支持。虽然有框架(如LLVM),但增加了开发成本。
- 碎片化风险: 如果每家都定义完全不同的扩展,会导致软件无法在不同厂家的RISC-V芯片上直接运行,削弱通用性。因此,行业正在推动在关键领域(如AI、矢量计算)形成事实上的标准扩展。
总结来说,您的理解是正确的。 RISC-V 通过“基础通用 + 可扩展/可自定义”的架构,完美地架起了通用计算和专用计算之间的桥梁。它既可以用作运行复杂操作系统的通用CPU,也可以通过定制化指令,变身为针对某个任务高度优化的专用加速器,或者将两者融合在同一颗芯片中,实现效率与灵活性的最佳结合。这正是RISC-V在当今计算架构变革中备受瞩目的主要原因。
本文发表于 0001-01-01,最后修改于 0001-01-01。
本站永久域名「 jiavvc.top 」,也可搜索「 极客油画 」找到我。

