01 — 编译器概念入门

目标: 用生活化的类比,让你理解"编译器"到底是什么、ScratchV 在做什么。 预计阅读: 15 分钟 前置要求: 会写一点点代码(任何语言都行)


目录
  1. 编译器是翻译官
  2. 翻译的四道工序
  3. 乐高积木:程序的零件
  4. 办公桌:数据的流转
  5. ScratchV 在翻译什么
  6. 为什么选 RISC-V
  7. 关键概念速查

1. 编译器是翻译官

想象你去联合国,一个中国代表在台上用中文演讲,台下坐着说英文、法文、阿拉伯文的听众。这时候需要翻译官——把中文转换成听众能懂的语言。

编译器就是程序的"翻译官"

你写的是 Python 代码(人能读懂的"高级语言"),CPU 只认识 0 和 1 组成的机器指令("低级语言")。编译器的工作就是:

你写的代码(Python/C++/...)
        │
        ▼
    ┌────────┐
    │ 编译器  │  ← "翻译官"
    └────────┘
        │
        ▼
CPU 能懂的 0/1 指令

ScratchV 翻译的是 AI 模型——把 ONNX 格式的神经网络模型文件,翻译成 RISC-V 芯片能执行的机器码。


2. 翻译的四道工序

真正的翻译官不是一句话直接翻出来,而是分步骤的。编译器也一样,通常分四道工序:

源程序(ONNX 模型 / DSL 代码)
        │
        ▼
┌───────────────────┐
│  ① 前端 (Frontend) │  ← 读懂原文,理解"它在说什么"
│  解析、理解结构     │     好比翻译官听清每个词的词性和语法
└───────┬───────────┘
        │  中间表示 (IR)
        ▼
┌───────────────────┐
│  ② 优化 (Optimizer) │  ← 把啰嗦的话变简洁
│  消除冗余、合并计算   │     "我非常非常想吃东西" → "我饿了"
└───────┬───────────┘
        │  优化后的 IR
        ▼
┌───────────────────┐
│  ③ 后端 (Backend)   │  ← 翻译成目标语言
│  生成目标平台的指令   │     中文 → 英文
└───────┬───────────┘
        │  汇编代码
        ▼
┌───────────────────┐
│  ④ 编码 (Encode)    │  ← 写出最终版本
│  汇编 → 二进制机器码  │     打印成文件
└───────────────────┘
        │
        ▼
    CPU 可执行的 0/1 文件

为什么要有"中间表示"(IR)?

想象翻译官把中文演讲稿先转成一堆简笔画/符号(不关心具体用哪种语言),然后再从这些符号出发翻成英文。

这个"简笔画/符号"就是 IR (Intermediate Representation,中间表示)

有了 IR 的好处: - 中文 → 英文 和 中文 → 法文 可以共享同一套"简笔画"(ScratchV 的 IR 同时支持生成 RISC-V 和 LLVM IR) - 在做具体翻译之前,可以先把"简笔画"里的废话去掉(这就是优化


3. 乐高积木:程序的零件

另一个理解编译器的方式:像拼乐高

乐高世界 编译器世界
乐高图纸(你想拼什么) 源程序(ONNX 模型)
分件员:把大图纸拆成小步骤 前端(解析、词法分析)
零件库:标准积木块 IR(三地址码、基本块)
拼装优化:减少多余步骤 优化器(死代码消除、常量折叠)
按说明书拼出实物 后端(代码生成、寄存器分配)

编译器就是这样:把一份"设计图纸"(程序),拆成"标准零件"(IR),再拼成"实物"(机器码)


4. 办公桌:数据的流转

还有一个比喻:

CPU 就像一个忙碌的办公桌,上面有: - 寄存器:手边的小便签,能立刻拿到(32 个,每个 32 位),速度最快 - 缓存 (Cache):桌上的文件架,拿取很快但容量有限 - 内存 (RAM):身后的文件柜,容量大但走过去拿要时间

编译器的工作之一是安排好数据放在哪——尽量把常用的放便签/文件架,少去文件柜拿。

这就是为什么会有"寄存器分配"、"缓存优化"这些话题——本质上是帮 CPU 的办公桌整理得更高效。


5. ScratchV 在翻译什么

ScratchV 做的事很具体:

.ai 模型文件 (ONNX)
   包含: Conv2D, MaxPool, Gemm, ReLU, Sigmoid...
        │
        ▼
   ScratchV 编译器
        │
        ▼
   RISC-V 芯片能跑的指令
   比如: add, mul, load, store, branch...

具体来说,ScratchV 把你训练好的 CNN 模型(能识别图片的那种),翻译成一段一段的 RISC-V CPU 指令,让 CPU 能逐步执行卷积池化矩阵乘法等计算。


6. 为什么选 RISC-V?
特性 说明
开源免费 不像 x86(Intel/AMD 私有)或 ARM(要授权费),任何人都能设计 RISC-V 芯片
简洁 基础指令只有 40 多条(x86 有上千条),适合学习和教学
正在崛起 从嵌入式到 AI 加速器,越来越多的公司在用 RISC-V
可验证 有很多开源仿真器,没有开发板也能跑

对 ScratchV 来说,RISC-V 的简洁意味着:我们真的可以"从零手写"一个编译器,把每个指令都搞懂


7. 关键概念速查

在阅读后续文档时,你会遇到这些词。这里先列出来,随时回来查:

概念 一句话解释 生活类比
ONNX AI 模型的标准存盘格式 .docx 之于 Word 文档
DSL 领域特定语言(ScratchV 自制的迷你编程语言) 宜家的组装说明书——只管"组装"这件事
IR (中间表示) 编译器的内部"通用语言" 翻译官的速记符号
三地址码 IR 的一种形式,每条指令最多三个操作数:c = a + b 一个简单的算式
RISC-V 一种开源的 CPU 指令集 CPU 的"母语"
汇编 (Assembly) 人类可读的 CPU 指令文本 把 0/1 机器码写成 add x1, x2, x3
寄存器 CPU 内部的超快速存储单元 办公桌上的便签
Q16.16 定点 用整数模拟小数的一种技巧(高16位=整数,低16位=小数) 用"分"代替"元"计算金额
静态指令数 编译器生成了多少条指令(不管执行多少次) 菜谱的步骤数
动态指令数 程序实际执行了多少条指令(循环里的指令会重复计数) 厨师实际做了多少次操作

接下来