跳转至

Introduction to the Microprocessor and Computer

Note

  • 微处理器发展史:存储程序思想 (von Neumann) → 4004 → x86 家族 → Intel 64 (IA-32e)
  • IEEE 754 浮点表示(本次课重点):格式三部分、特殊值、subnormal、舍入模式、浮点运算三步、经典精度陷阱
  • 教材:Brey《The Intel Microprocessors》8th Edition,第一章一次课讲完(很多内容大家已有基础)

本章概览

  • 存储程序 (stored program):von Neumann 率先提出把指令存入内存的系统——比重新接线编程高效得多,可编程机器由此催生了程序与编程语言
  • 4004(第一款微处理器):P-channel MOSFET 工艺,50 KIPs(千指令/秒);对比 1946 年 30 吨的 ENIAC 的 100,000 指令/秒——差别是 4004 重量不足一盎司;4 位微处理器最早用于游戏机与小型控制系统
  • 性能演进技术:superscalar(超标量)利用指令级并行,但后续指令往往相互依赖、第二条流水线利用率低 → 乱序执行 (Out-of-order Execution):按数据流图而非程序顺序执行,在指令窗口中向前查找就绪指令
  • Intel 64 架构:线性地址空间 64 位、物理地址空间最高 52 位;引入 IA-32e 模式,含两个子模式——Compatibility mode(64 位系统直接运行旧 32 位软件)与 64-bit mode

IEEE 754 浮点表示

三部分构成

IEEE 754 采用科学计数法的思想,由三部分组成:

  • sign bit:0 为正,1 为负
  • biased exponent:指数加偏移 (bias) 便于比较;全 0 与全 1 被保留用于特殊值
  • normalized fraction / mantissa:规格化数的尾数有一个不存储的 hidden bit(隐含的 1)
\[(-1)^{\text{sign}} \times (1 + \text{fraction}) \times 2^{\text{exponent} - \text{bias}}\]

以 binary32(单精度)为例:sign 1 位 + exponent 8 位 + fraction 23 位,bias = 127。

课件 · IEEE 754 格式与 binary32 实例

为什么浮点数不用补码?

  • 定点整数用二进制补码表示,而浮点数改用符号-数值分离法,原因:
    • 补码基于模运算原理,要求数字定长;浮点数是不定长的,补码的基本前提不存在
    • 浮点数基本上没有无符号数,都是带符号的,干脆把符号位单独拿出来
    • 补码表示中 0 只有一种表示(非对称);符号-数值分离可以表示 +0 和 −0 两个 0——在微积分求极限时"趋向 0⁺ 还是 0⁻"是有意义的,浮点计算里有价值

特殊值 (Special Values)

类型 指数部分 尾数部分 说明
\(\pm 0\) 全 0 全 0 符号位可 0 可 1 → 正零/负零
\(\pm\infty\) 全 1 全 0 指数用尽、尾数无 → 数足够大/小,符号定方向
NaN 全 1 ≠ 0 Not a Number:0/0、负数开根号等不存在的结果
Normal number 非 0 且非全 1 任意 正常数,隐含 1
Subnormal number 全 0 ≠ 0 极小数,见下

Subnormal Numbers(非规格化数)

  • 介于最小 normal number(\(1.0 \times 2^{-126}\))与 0 之间的数
  • 表示:指数全 0、尾数非全 0,不加隐含 1(single 精度下指数为 \(-126\)):

    \[ \text{subnormal} = (-1)^{\text{sign}} \times \text{fraction} \times 2^{1-\text{bias}} \]
  • 设计意图:按此公式计算的 subnormal 与最小的 normal number 衔接最紧密、最平滑——差在最末一个 bit,IEEE 委员会(图灵奖得主,数值计算专家)的精细设计

  • 两种下溢处理策略(Abrupt Underflow vs Gradual Underflow):
    • Motorola:flush to zero——小到一定程度突然当作 0,保性能、降精度
    • Intel:gradual underflow——subnormal 仍是数、仍可计算、精度保留,但用软件模拟的方式执行,保精度、降性能(速度慢 10 倍以上)
    • 真实案例:早期 Matlab 解偏微分方程,解到一半速度突然慢 10 倍——就是掉进了 subnormal 区间;知道这个知识就可以调整算法跳出去

舍入模式(5 种)

IEEE 754 明确定义了 5 种舍入,统一舍入保证不同实现的浮点结果一致:

模式 +11.5 +12.5 −11.5 −12.5
to nearest, ties to even(默认) +12.0 +12.0 −12.0 −12.0
to nearest, ties away from zero +12.0 +13.0 −12.0 −13.0
toward 0 +11.0 +12.0 −11.0 −12.0
toward +∞ +12.0 +13.0 −11.0 −12.0
toward −∞ +11.0 +12.0 −12.0 −13.0
  • 默认 roundTiesToEven:往末尾变成偶数的方向舍(11.5 → 12,12.5 → 12)
  • 伏笔:做除法有两种手段——除法指令和移位;负数时两者结果有差异,本质就是舍入方式不同;懂这个原理就能用算法补偿,让结果一致

浮点运算的三个步骤

两个浮点数做加法:

  1. 指数对齐:往大的指数对齐
  2. 尾数运算:对齐后对尾数部分做计算
  3. 舍入/截断:中间结果精度超出表示范围(如 single 尾数 23 位)时必须舍入

经典精度陷阱 (Accuracy Problem)

float sum = 0.0f, x = 1.0f;
for (int i = 0; i < N; i++) sum += x;
  • N = 3×10⁶ 时 sum = 3×10⁶,正确
  • N = 3×10⁷ 时 sum = 16777216 = 2²⁴,加不动了
  • 原因:到 2²⁴ 后再 +1,指数对齐后这个 1 排在第 24 位,而有效尾数只有 23 位,第 24 位的 1 被直接丢掉
  • 解决:换更高精度(double)、分段求和等——知道道理就有很多办法;数值计算优化(自动做等价变换保精度/提性能)是一个专门且稀缺的研究方向

AI 中的浮点格式

AI 训练/推理对精度不敏感(不像科学计算对精度和边界条件敏感),因此降精度换性能:

格式 指数 尾数 说明
FP32 8 23 传统单精度
TF32 8 10 NVIDIA Ampere:表示范围不变,精度降下来
BF16 8 7 Google Brain/TPU:更狠地砍尾数
FP16 5 10 指数也缩,范围变小

A100 上 TF32 相比 FP32 推理性能大幅提升。此外 IEEE 754-2019 还有十进制浮点的讨论(用十进制表示十进制、精度更高),但因巨大商业价值未形成共识——当年 Intel 敢把 8087 的标准推向全球也是同样的商业逻辑。

课件 · AI 的新浮点格式 TF32 / BF16 / FP16

Note

  • 教材只有一本:Brey《The Intel Microprocessors》8th Edition
  • 课件与作业答案都发布在 QQ 群,作业不需要提交,自己对照答案即可
  • 助教(上一届学长)已拉进钉钉群和 QQ 群,有问题可问助教或老师
  • 周五的实验不需要去实验室,自己做就行