一、从 Hello World 看计算机系统全貌
1.1 为什么需要系统视角
系统方向的研究者在讨论时,经常为一个问题争论不休——”当运行 print("hello world") 的时候,整个计算机系统都发生了什么?”体系结构有体系结构的看法,操作系统有操作系统的看法,编译有编译的看法。
这引出本节的核心:从系统视角理解计算机的完整工作流程。
1.2 编译与链接过程
源代码 hello.c 变成可执行文件经历了以下步骤:
| 步骤 | 输入 | 输出 | 工具/阶段 |
|---|---|---|---|
| 预处理 | hello.c |
hello.i |
Preprocessor(展开宏、include) |
| 编译 | hello.i |
hello.s |
Compiler(生成汇编) |
| 汇编 | hello.s |
hello.o |
Assembler(生成机器码) |
| 链接 | hello.o + 库 |
hello(可执行) |
Linker(静态链接 printf 等) |
RISC-V 的汇编很简单——一条汇编对应一条机器指令,手抄手册也能抄出来。x86 就复杂得多,IO 操作和寄存器操作是不同的指令。
1.3 按下回车后发生的事
在命令行中键入 ./hello 并回车:
- 键盘中断:键盘连在 USB Controller → I/O Bridge(南桥),速度很慢。按键产生一个中断信号
- 中断处理:CPU 收到中断 → 跳转到中断服务程序 → 读取命令
- 加载可执行文件:Shell 通知操作系统要运行
hello→ 从硬盘找到可执行文件 → 加载到内存(不在 Cache 里,甚至可能不在内存里,需要从磁盘读) - 执行指令:指令从 Memory → CPU(取指、译码、执行、访存、写回)
- 输出到显示器:
printf最终将 “hello world” 字符串通过 I/O 总线传到显卡/显示器
数据在中间输出来回运转——每一步操作都绕不过去。Hello World 短短的代码,实际涉及了整个计算机系统的每一个层次。
1.4 系统瓶颈
在以上流程中,低速 I/O 设备(键盘、磁盘、显示器)和 Memory 是主要瓶颈。
- CPU 主频 3-4GHz → 一个时钟周期约 0.25-0.33ns
- 内存访问延迟 ~50-100ns
- 磁盘访问延迟 ~毫秒级
CPU 跑得再快也没用——很多时候计算卡在数据读不进来。以后遇到的所有系统,计算量只是问题的一部分,更多的瓶颈在 Memory 访问。
二、Cache 与 Memory 层次结构
2.1 为什么需要 Cache
代码段和数据段都在同一块内存中。CPU 每个周期都需要取指令,同时也要读写数据——如果不做优化,两者会频繁冲突。
解决方案:
- CPU 内部将 I-MEM(指令存储器) 和 D-MEM(数据存储器) 分开(Harvard 架构)
- 指令 Cache:一次不只取一条指令(32 位),而是一次取一整行(Cache Line),例如 128 位(4 条指令)甚至 256 位
- 减少了对 Memory 的访问次数,也减少了指令和数据争用总线
2.2 内存带宽的倍增技术
DDR 内存使用多种技术来提升有效带宽:
- 双边沿采样:上升沿和下降沿都传输数据(DDR = Double Data Rate)
- 倍频技术:总线频率的 4 倍有效数据率
- 宽数据总线:从 64 位扩展到 128 位乃至更宽
2.3 程序局部性与 Cache 友好代码
两个嵌套 for 循环遍历二维数组——调整 i 和 j 的循环顺序,性能可能差几倍。因为 Cache 每次取的是一整行的数据(不是只取一个数),如果按行优先顺序访问,每次取到的数据都能被充分利用。
三、指令集体系结构(ISA)的角色
3.1 ISA 是必不可少的抽象层
没有指令集体系结构,软件无法使用计算机硬件;没有它,一台计算机不能称为通用计算机。
ISA 的三大作用:
- 软件-硬件接口:编译器将高级语言翻译为 ISA 指令,硬件只需实现这套指令
- 兼容性保障:同一套 ISA 上的所有软件都能运行
- 分工界面:ISA 以上是软件的事(编译器、OS),以下是硬件的事(微架构)
3.2 大端与小端
- 小端(Little-Endian):低位字节在低地址(x86、RISC-V 通用)
- 大端(Big-Endian):高位字节在低地址(网络协议)
历史上两套并存,多次有人提议统一,但因为有大量已有设备和代码,无法改变。这个世界有很多东西看着很奇怪,背后都有历史原因。
3.3 通用性与专用性的权衡
通用处理器(CPU) 的优势:
- 任何代码都能运行,灵活性最高
- 生态成熟,软件丰富
专用处理器(如 TPU) 的问题:
- 针对特定神经网络架构设计 → 当 AI 模型架构变化时(如从 CNN 变到 Transformer),硬件跟不上
- 投资风险大——万一算法变了,硬件全部淘汰
做研究时要记住自己的 motivation——不忘初心。做领域专用架构(Domain-Specific Architecture)能提升性能,但出了这个领域就失效了。GPU 的成功在于它是”通用目的的图形处理器”(GPGPU),靠灵活性而不是专用性取胜。
四、计算机系统的三大瓶颈
4.1 存储墙(Memory Wall)
- CPU 算力增长远超内存带宽增长
- GPU 使用 HBM(高带宽内存)缓解,但成本更高
- 分布式系统中,节点间通信是更大的瓶颈
4.2 功耗墙(Power Wall)
- 奔腾 4 时代(~2004 年)主频已达到 4GHz,此后不再增长
- 继续提升频率导致功耗和散热不可接受
- 转向多核路线:不提高单核频率,而增加核心数
4.3 指令级并行墙(ILP Wall)
- 单条指令流中可挖掘的并行度有限
- 转向数据级并行(SIMD、GPU)和线程级并行
五、计算机性能评价
5.1 核心指标
计算机评价就三件事——Performance、Price、Power。
性能(Performance)的两个维度:
| 指标 | 英文 | 含义 |
|---|---|---|
| 响应时间 | Response Time / Latency | 单个任务从开始到完成的时间 |
| 吞吐率 | Throughput / Bandwidth | 单位时间内完成的任务数量 |
流水线增加了单条指令的响应时间(加了锁存器延迟),但大幅提升了吞吐率。评价 CPU 时要用大量指令(百万级以上)测总执行时间,而不是一条指令的时间。
5.2 CPU 性能公式(Iron Law)
\[\text{执行时间} = \text{指令数} \times \text{CPI} \times \text{时钟周期}\]| 因子 | 英文 | 受谁影响 |
|---|---|---|
| 指令数 | Instruction Count | 编译器 + ISA |
| 每指令周期数 | CPI (Cycles Per Instruction) | 微架构 |
| 时钟周期 | Clock Cycle Time | 工艺 + 微架构 |
系统性能和 CPU 性能不等价——系统慢可能是 OS 调度、IO、memory 带宽的问题。跟别人争论时,要”掰开了揉碎了”讲清楚到底是哪部分慢。
5.3 基准测试程序
- SPEC CPU:行业公认的标准基准测试套件
- 公布性能数据时的策略:对自己有利的指标就用,不利的就解释为什么这不重要
六、特权指令与多核同步简介
6.1 特权指令(CSR 相关)
RISC-V 的特权指令(CSR 读写)涉及与操作系统的交互,含义比普通计算指令更复杂。每条特权指令对应特定的系统功能(中断管理、地址翻译、权限控制等)。
6.2 原子指令与 Fence
原子指令(Atomic Instructions):多核环境下,两个核同时访问同一内存地址时,必须保证”读-改-写”序列的原子性——否则两个核的写入结果完全不可控。
Fence 指令(内存屏障):确保多核之间的内存访问顺序。当一个核对某个内存地址做了写操作,需要确保另一个核能看到这个更新。
原子指令和 Fence 对操作系统非常重要——没有原子指令,多核同步几乎无法正确实现。
七、AI 时代的体系结构探索
7.1 存算一体(Processing-in-Memory)
在 Memory 内部放置简单计算单元,数据不搬出就能做简单运算。曾是研究热点但遇到工程困难。
7.2 可重构计算(Reconfigurable Architecture)
FPGA 上的思路:根据应用场景动态切换硬件电路。例如平时跑 5 级流水 CPU,需要大量乘法时”烧入”乘法加速器。
7.3 领域专用架构的挑战
特定领域的架构可以提升性能(因为你摒弃了不需要的东西),但当环境变化时,这些专用设备可能全部淘汰。Transformer 已经流行多年了,万一后面有更好的框架,你专门为 Transformer 做的硬件怎么办?所以大家宁愿买通用 GPU。
课程事务
- Lab 进度:部分同学已实现 Forwarding/ByPass、分支预测
- 后续实验:Memory 接口、Cache、CSR 特权指令、原子指令、Fence
- 优先保证功能正确,有余力再做性能优化