开篇把 CPU 拆开最里面是什么一台电脑能做的事情多到数不清——渲染画面、播放音乐、跑神经网络、加密解密。但如果你把 CPU 一层层拆开拆到最核心的那个部件会发现它只会做二十来件事加、减、与、或、非、异或、左移、右移、比大小……就这些。没有乘法早期没有除法更没有渲染或解密。这个部件就叫ALUArithmetic Logic Unit算术逻辑单元。所有复杂的事情都是由这二十来件简单的事重复几十亿次拼出来的。这篇文章要做的是从一个最简单的加法开始一步步把 ALU 拼出来。第一部分ALU 是什么一、先看它长什么样从外面看┌─────────────┐ 输入 A ────────→│ │ (n位) │ │ │ ALU │───────→ 结果 (n位) 输入 B ────────→│ │ (n位) │ │───────→ 状态标志 │ │ 操作码 ────────→│ │ (几位) └─────────────┘四个东西端口作用A、B两个操作数⭐操作码Opcode告诉它这次要做什么结果算出来的值⭐标志位Flags关于结果的额外信息一个具体例子A 0101 (十进制 5) B 0011 (十进制 3) 操作码 000加法 → 结果 1000 (8) 操作码 001减法 → 结果 0010 (2) 操作码 010与 → 结果 0001 操作码 011或 → 结果 0111同一套电路靠操作码切换行为。这是 ALU 设计的核心思想——不是造二十个电路而是造一个能变形的电路。二、它在 CPU 里的位置┌──────────────────────────────────────────┐ │ CPU │ │ │ │ ┌──────────┐ │ │ │ 寄存器组 │←─────┐ │ │ └────┬─────┘ │ │ │ │ │ 结果写回 │ │ 取操作数 │ │ │ ↓ │ │ │ ┌─────────────────┴──┐ │ │ │ ★ ALU │ │ │ └────────────────────┘ │ │ ↑ │ │ 操作码 │ │ │ │ │ ┌────┴─────┐ │ │ │ 控制单元 │ ← 解码指令 │ │ └──────────┘ │ └──────────────────────────────────────────┘一条指令的执行流程① 取指令 ADD R1, R2 ② 解码 ★ 控制单元识别出这是加法产生操作码 000 ③ 取数 从寄存器 R1、R2 读出值送进 ALU 的 A、B ④ ★ 计算 ALU 执行加法 ⑤ 写回 结果存回 R1第二部分从加法开始ALU 里最复杂、也最基础的部分是加法器。先把它搞定。三、一位加法半加器先看最小的问题两个 1 位二进制数相加有多少种情况0 0 0 0 1 1 1 0 1 1 1 10 ← ★ 注意结果是两位最后一行是关键11 在二进制里等于 2写作10。1 1 10 ↑↑ ││ │└─ 本位Sum 0 └── 进位Carry 1列成真值表AB进位 Carry本位 Sum0000010110011110⭐ 观察这两列先看 Sum 列0, 1, 1, 0这正是异或XOR的输出异或的本质就是不进位的加法。Sum A ⊕ B再看 Carry 列0, 0, 0, 1这正是与AND的输出——两个都是 1 才输出 1。Carry A · B半加器完成┌──────────────┐ A ────→│ │───→ Sum A ⊕ B │ 半加器 │ B ────→│ │───→ Carry A · B └──────────────┘电路A ─┬────────⊕────→ Sum │ ╱ B ─┼──────╱ │ └───┬───────→ Carry │ A ─────┘只用两个门一个异或一个与。为什么叫半加器它只能处理【本位的两个数】 ↓ ★ 无法接收【上一位传来的进位】 ↓ 所以只完成了一半的工作四、一位加法全加器问题多位加法需要处理进位做一次多位加法看看1 0 1 1 (11) 0 1 1 0 (6) ─────────从最右边开始一位一位加第0位 1 0 1 进位 0 第1位 1 1 10 本位 0★ 进位 1 第2位 0 1 ★1 10 ← ★ 这里要加上上一位的进位 第3位 1 0 ★1 10所以每一位实际上要加【三个数】A、B、和上一位的进位。全加器的真值表三个输入A、B、Cin进位输入ABCinCoutSum0000000101010010111010001101101101011111⭐ 推导 Sum先看 Sum 列0, 1, 1, 0, 1, 0, 0, 1规律★ 三个输入里 1 的个数是奇数时Sum 1。这正是三个数异或的结果Sum A ⊕ B ⊕ Cin验证一下A1, B1, Cin1 1⊕1 0 0⊕1 1 ✅ 对上了⭐异或的奇偶性特性又出现了。这不是巧合——“不进位的加法本质就是模 2 加法”而多个数的模 2 加法就是看 1 的个数的奇偶性。⭐ 推导 Cout再看 Cout 列什么时候有进位★ 三个输入里至少有两个是 1写成逻辑式Cout A·B B·Cin A·Cin意思是“A和B都是1” 或 “B和Cin都是1” 或 “A和Cin都是1”。更省门的写法换个角度想进位是怎么产生的情况①★ A 和 B 本身就都是 1 → 必然进位 不管 Cin 是什么 情况②★ A 和 B 里恰好有一个是 1而 Cin 也是 1 → 1 0 1 10 → 进位写成式子Cout A·B (A⊕B)·Cin ~~~~ ~~~~~~~~~~ 情况① 情况②这两个名字后面会反复用到G A·B 叫「生成」Generate—— 这一位自己就能产生进位 P A⊕B 叫「传播」Propagate—— 这一位会把下面的进位传上去★ 记住这两个字母第七节的加速算法全靠它们。全加器 两个半加器 一个或门A ──┬──────┐ │ 半加器① ├── S1 ──┬──────┐ B ──┴──────┘ │ 半加器② ├──→ Sum │ │ Cin ───────────────────────┴──────────┘ │ ┌──────┴──── C2 │ C1 ──────────────┤ ┌────┴──→ Cout │ (或门)文字描述① 半加器① 算 A B → 得到 S1 A⊕BC1 A·B ② 半加器② 算 S1 Cin → 得到 Sum S1⊕Cin A⊕B⊕Cin ✅ → 得到 C2 S1·Cin (A⊕B)·Cin ③ ★ Cout C1 C2 A·B (A⊕B)·Cin ✅五、多位加法串行进位加法器把全加器串起来要做 4 位加法就用 4 个全加器A3 B3 A2 B2 A1 B1 A0 B0 │ │ │ │ │ │ │ │ ┌┴──┴┐ ┌┴──┴┐ ┌┴──┴┐ ┌┴──┴┐ ←──┤ FA3├←────┤ FA2├←────┤ FA1├←────┤ FA0├←── Cin0 Cout └─┬──┘ C3 └─┬──┘ C2 └─┬──┘ C1 └─┬──┘ │ │ │ │ S3 S2 S1 S0进位像波浪一样从右往左传所以叫「行波进位加法器」Ripple Carry Adder。走一遍例子A 1011 (11) B 0110 (6)第0位 A01, B00, Cin0 Sum1, Cout0 → S0 1 第1位 A11, B11, Cin0 ← ★ 要等上一位算完 Sum0, Cout1 → S1 0 第2位 A20, B21, Cin1 ← ★ 要等上一位算完 Sum0, Cout1 → S2 0 第3位 A31, B30, Cin1 ← ★ 要等上一位算完 Sum0, Cout1 → S3 0 结果 Cout1, S 0001 ★ 也就是 10001 17 ✅ 11617⭐ 致命问题速度第0位算完 → 第1位才能开始 → 第2位 → 第3位 → ... ~~~~~~~~ ★ 完全串行一个都不能跳延迟计算假设一个全加器的进位延迟是 2 个门延迟 8 位加法 → 8 × 2 16 个门延迟 32 位加法 → 32 × 2 64 个门延迟 64 位加法 → ★ 64 × 2 128 个门延迟这是无法接受的。CPU 一个时钟周期可能只有二三十个门延迟的时间。一个 64 位加法要 128 个门延迟意味着加法要占好几个周期。六、⭐ 加速超前进位核心思路串行慢是因为每一位都要等前一位的进位。如果能【不等】直接算出每一位的进位呢回顾两个概念从全加器的进位公式出发Cout A·B (A⊕B)·Cin ~~~ ~~~~~ G P符号定义含义⭐G生成G A·B这一位自己就产生进位⭐P传播P A⊕B这一位会把进来的进位传出去所以C(i1) Gi Pi · Ci递归展开第 1 位的进位C1 G0 P0·C0第 2 位的进位把 C1 代入C2 G1 P1·C1 G1 P1·(G0 P0·C0) G1 P1·G0 P1·P0·C0 ~~ ~~~~~ ~~~~~~~~第 3 位C3 G2 P2·G1 P2·P1·G0 P2·P1·P0·C0第 4 位C4 G3 P3·G2 P3·P2·G1 P3·P2·P1·G0 P3·P2·P1·P0·C0⭐ 关键洞察看这些式子C1、C2、C3、C4 全都只依赖 G、P 和最初的 C0 ↓ ★ 而 G、P 只依赖 A 和 B可以【同时】算出来 ↓ ★ 所以 C1~C4 也可以【同时】算出来电路结构变成第1层 A,B → ★ 同时算出所有 G 和 P 1 个门延迟 第2层 G,P → ★ 同时算出所有进位 C1~C4 2 个门延迟 第3层 P,C → ★ 同时算出所有 Sum 1 个门延迟 Sum(i) Pi ⊕ Ci ──────────────────────── ★ 总共只要 4 个门延迟效果对比位宽串行进位⭐ 超前进位4 位8 门延迟4 门延迟8 位16416 位32⭐约 8分组64 位⭐128⭐约 12多级分组为什么大位宽要分组因为 C64 的展开式会有 65 项其中一项是 64 个 P 相与——★ 一个门不可能接 64 个输入扇入限制。所以实际做法是★ 每 4 位一组做超前进位组和组之间再做一层超前进位。这叫「多级超前进位」是现代 CPU 的标准做法。代价✅ 速度从 O(n) 降到 O(log n) ❌ 面积★ 门的数量大幅增加 ❌ 功耗★ 门多了耗电也多这是硬件设计里最典型的权衡用面积换速度。第三部分减法七、⭐ 减法就是加法思路不造减法器造一个减法器 → 又要一套电路 → 浪费 ★ 换个思路A - B A (-B) ↓ 只要能求出 -B就能用加法器做减法二进制里的负数补码先看一个熟悉的例子——时钟。现在 3 点往前拨 2 小时 1 点 现在 3 点往后拨 10 小时 1 点 ★ 结果一样 ↓ ★ 在 12 进制的时钟里-2 等价于 10因为-2 12 10。⭐这就是补码的思想在一个会溢出回绕的系统里减去一个数 加上它的补数。4 位二进制的补码4 位能表示 16 个数0~15所以模是 16。-B 的补码 16 - B举例求 -3 的补码16 - 3 13 1101 ↓ ★ 在 4 位系统里1101 既可以看作 13也可以看作 -3验证5 - 3 应该等于 20101 (5) 1101 (-3 的补码) ──────── 10010 ↑ ★ 第 5 位溢出4 位系统里被丢弃 ↓ 0010 (2) ✅ 正确⭐ 怎么快速求补码公式-B ~B 1取反再加一验证 -33 0011 ~3 1100 ← ★ 每一位取反 ~31 1101 ← ★ 加 1 和上面算的 16-31101 ✅ 一致为什么取反加一等于模减去对 4 位数 B ~B 1111 15 ★ 因为每一位一个0一个1 ↓ ~B 15 - B ↓ ~B 1 16 - B ★ -B 的补码一行推导说明了取反加一的来历。八、⭐ 用异或实现要不要取反回到异或的一个性质A ⊕ 0 A ★ 原样通过 A ⊕ 1 Ā ★ 取反异或门可以当受控反相器用。一个输入接数据另一个输入当开关。加减复用电路SUB0加法1减法 │ B3 ──────────────⊕───→ 送进加法器 │ B2 ──────────────⊕───→ │ B1 ──────────────⊕───→ │ B0 ──────────────⊕───→ │ └──────→ ★ 同时接到 Cin走一遍两种情况SUB 0做加法B 各位 ⊕ 0 B 各位 ★ 原样送进去 Cin 0 ↓ ★ 结果 A BSUB 1做减法B 各位 ⊕ 1 ~B ★ 取反送进去 Cin 1 ★ 同时加 1 ↓ ★ 结果 A ~B 1 A (-B) A - B⭐这是 ALU 设计里最优雅的一个技巧★ 一排异或门 一根控制线让加法器兼职做减法。不用造第二套电路。完整的加减法器SUB ──┬─────────────────────────────┐ │ │ B3 ──⊕──┐ │ B2 ──⊕──┤ │ B1 ──⊕──┼──→ ┌─────────────┐ │ B0 ──⊕──┘ │ │ │ │ 加法器 │←───────┘ Cin SUB A3 ─────────→│ │ A2 ─────────→│ │───→ 结果 A1 ─────────→│ │───→ Cout A0 ─────────→└─────────────┘第四部分逻辑运算九、四个基本逻辑操作算术部分搞定了逻辑部分简单得多——每一位独立没有进位。AND与A B │ 输出 ─────┼───── 0 0 │ 0 0 1 │ 0 1 0 │ 0 1 1 │ 1 ★ 都是 1 才是 1用途★ 掩码Mask——把某些位清零1011 0110 0000 1111 ← ★ 掩码 ─────────── 0000 0110 ★ 只保留低 4 位OR或A B │ 输出 ─────┼───── 0 0 │ 0 0 1 │ 1 1 0 │ 1 1 1 │ 1 ★ 有一个 1 就是 1用途★ 置位——把某些位设为 11011 0000 | 0000 0110 ← ★ 要置位的位置 ─────────── 1011 0110XOR异或A B │ 输出 ─────┼───── 0 0 │ 0 0 1 │ 1 1 0 │ 1 1 1 │ 0 ★ 不一样才是 1用途★ 翻转指定位 X ⊕ 掩码 ★ 判断相等 A ⊕ B 0 则 A B ★ 清零 X ⊕ X 0NOT非A │ 输出 ──┼───── 0 │ 1 1 │ 0NOT 只有一个操作数但 ALU 是双输入的。实现方法★NOT AA ⊕ 1111...1和全 1 异或或者直接在电路里加一路反相器。十、逻辑运算的电路特点【算术运算】 ★ 位与位之间有进位依赖 ★ 必须串行或用超前进位加速 【逻辑运算】 ★ 每一位完全独立 ★ 所有位【同时】算完只要 1 个门延迟A3 ─┐ A2 ─┐ A1 ─┐ A0 ─┐ ← ★ 4 个门同时工作 B3 ─┘ B2 ─┘ B1 ─┘ B0 ─┘ │ │ │ │ R3 R2 R1 R0这也是为什么逻辑运算指令通常比算术运算快。第五部分移位运算十一、三种移位逻辑左移SHL1011 0110 ↓ 左移 1 位 0110 1100 ~ ~ 最高位丢弃 ★ 低位补 0效果★ 相当于乘以 20000 0101 (5) ↓ 左移 1 0000 1010 (10) ✅逻辑右移SHR1011 0110 ↓ 右移 1 位 0101 1011 ~ ~ ★ 高位补 0 最低位丢弃效果★ 无符号数除以 20000 1010 (10) ↓ 右移 1 0000 0101 (5) ✅⭐ 算术右移SAR问题如果是负数呢1111 1010 (-6补码) ↓ 逻辑右移 1 0111 1101 (125) 完全错了原因★ 补码的最高位是符号位补 0 把负数变成了正数。解法算术右移★ 高位补符号位1111 1010 (-6) ↓ 算术右移 1 1111 1101 (-3) ✅ 正确 ~ ★ 补的是原来的最高位1三种移位对照操作左边补什么用途逻辑左移右边补 0×2逻辑右移⭐ 左边补0无符号 ÷2算术右移⭐ 左边补符号位有符号 ÷2这是一个经典 bug 来源C 语言里对有符号数是算术右移对无符号数是逻辑右移。★ 类型写错结果完全不同。循环移位ROL / ROR1011 0110 ↓ 循环左移 1 0110 1101 ~ ★ 移出去的最高位补到最低位用途加密算法、哈希函数里很常见。十二、桶形移位器朴素做法的问题要移 5 位 → 执行 5 次移 1 位 ↓ ★ 太慢而且移位次数不固定⭐ 桶形移位器Barrel Shifter思路用多路选择器一次到位。移位量 5 101二进制 ↓ 分解成 移 4 位 移 1 位 ↓ ★ 用 3 级电路对应 4、2、1搞定任意 0~7 位移位输入 ↓ ┌─────────┐ │ 移 4 位? │← S2 ★ 第 1 级 └────┬────┘ ↓ ┌─────────┐ │ 移 2 位? │← S1 ★ 第 2 级 └────┬────┘ ↓ ┌─────────┐ │ 移 1 位? │← S0 ★ 第 3 级 └────┬────┘ ↓ 输出n 位移位器只需 log₂(n) 级。8 位 → 3 级 32 位 → 5 级 64 位 → ★ 6 级又是树形结构 log 级延迟的思想。和第一篇文章里异或树的道理完全一样。第六部分怎么选操作十三、多路选择器问题ALU 里同时有 加法器、AND 阵列、OR 阵列、XOR 阵列、移位器…… ↓ ★ 它们【全都在工作】全都算出了结果 ↓ ★ 但只有一个结果该被输出解法多路选择器MUX加法结果 ──→┐ AND 结果 ──→┤ OR 结果 ──→┤ MUX ├──→ ★ 最终输出 XOR 结果 ──→┤ 移位结果 ──→┘ ↑ 操作码MUX 的作用★ 根据选择信号从多个输入里挑一个输出。2 选 1 MUX 的实现输出 (A · S̄) (B · S) S 0 → 输出 A S 1 → 输出 BA ──┬────┐ │ │ S̄ ──┘ ├──|──→ 输出 │ (或) B ──┬────┘ │ S ──┘多选 1 就是把这个结构堆叠起来。十四、操作码设计一个 4 位操作码的例子操作码操作说明0000ADDA B0001SUBA - B0010ANDA B0011ORA | B0100XORA ^ B0101NOT~A0110SHLA 10111SHRA 11000SAR算术右移1001CMP⭐A - B但不保存结果只更新标志位1010INCA 11011DECA - 11100PASS A直接输出 A1101PASS B直接输出 B注意CMP比较★ 它的电路和减法完全一样只是不写回结果。比较大小本质就是减一下看看正负。⭐ 一个经典设计MIPS 的 1 位 ALU把前面讲的全部组合起来Ainvert Binvert Operation(2位) │ │ │ A ────┬─────────────⊕ │ │ │ │ │ │ │ ┌────┘ │ │ │ │ │ │ B ────┼────────┼──────────────⊕ │ │ │ │ │ │ ↓ ↓ │ │ ┌──────────────────┐ │ ├────→│ AND │──────→┐ │ │ └──────────────────┘ │ │ │ ┌──────────────────┐ │ │ ├────→│ OR │──────→┤ │ │ └──────────────────┘ ├──MUX──→ 结果 │ ┌──────────────────┐ │ ↑ └────→│ 全加器 │──────→┤ │ Cin ────────→│ │ │ │ └────────┬─────────┘ │ │ │ ┌───→┘ │ Cout Less │ │四条控制线就能覆盖大部分操作AinvBinvOp操作原理0000AND直接选 AND0001OR直接选 OR0010ADD直接选加法0110⭐SUBB 取反 Cin11100⭐NOR德摩根~A ~B ~(A|B)⭐注意最后一行不用专门造 NOR 电路——把 A、B 都取反再做 AND就是 NOR。这是德摩根定律的硬件应用。第七部分标志位十五、⭐ 四个核心标志ALU 除了算出结果还要报告这个结果有什么特点。标志全称含义ZZero结果是 0NNegative⭐ 结果为负最高位是 1CCarry⭐无符号运算溢出VOverflow⭐有符号运算溢出Z 标志结果为零Z 1 当且仅当 所有结果位都是 0电路★ 所有位做或非NORR7 ─┐ R6 ─┤ R5 ─┤ R4 ─┼── NOR ──→ Z R3 ─┤ R2 ─┤ R1 ─┤ R0 ─┘用途★ 判断两数是否相等CMP A, B ← 执行 A - B JZ label ← ★ 如果 Z1差为0说明 AB跳转N 标志结果为负N 结果的最高位因为补码表示里★ 最高位就是符号位。0xxx xxxx → 正数N0 1xxx xxxx → 负数N1电路★ 一根线直接把最高位引出来。十六、⭐⭐ Carry 和 Overflow 的区别这是 ALU 里最容易混淆的一对概念。必须讲清楚。核心区别【Carry】 ★ 把结果当【无符号数】看超出范围了吗 【Overflow】★ 把结果当【有符号数】看超出范围了吗同一组二进制位可以有两种解读方式。★ 所以需要两个不同的标志分别报告两种解读下的溢出情况。8 位数的两种解读范围【无符号】 0000 0000 ~ 1111 1111 → 0 ~ 255 【有符号】 1000 0000 ~ 0111 1111 → -128 ~ 127例子①C1 但 V01111 1111 (无符号 255 / 有符号 -1) 0000 0001 (无符号 1 / 有符号 1) ───────────── 1 0000 0000 ~ ★ 进位两种解读【无符号视角】 255 1 256 ★ 超出 0~255 范围 → C 1 ✅ 【有符号视角】 -1 1 0 ★ 0 在 -128~127 范围内 → V 0 ✅例子②C0 但 V10111 1111 (无符号 127 / 有符号 127) 0000 0001 (无符号 1 / 有符号 1) ───────────── 1000 0000 ~ ★ 没有进位两种解读【无符号视角】 127 1 128 ★ 128 在 0~255 范围内 → C 0 ✅ 【有符号视角】 127 1 ? 结果 1000 0000 -128 ★ 两个正数相加得负数明显错了 → V 1 ✅例子③两个都是 11000 0000 (无符号 128 / 有符号 -128) 1000 0000 (无符号 128 / 有符号 -128) ───────────── 1 0000 0000【无符号】 128128 256超出 → C 1 【有符号】 -128 -128 -256超出 → V 1⭐ Overflow 的判定电路方法一看符号位规律★ 溢出只在两种情况发生 ① 正 正 负 ② 负 负 正 ★ 一正一负相加永远不会溢出 因为结果的绝对值一定比两个操作数都小方法二更简洁V C(n) ⊕ C(n-1) ~~~~ ~~~~~~ 最高位的进位输出 次高位的进位输出理解如果进入最高位的进位和从最高位出去的进位不一样 ↓ ★ 说明符号位被错误地改变了 ↓ 溢出验证例子②0111 1111 0000 0001 ↓ 次高位产生进位 C6→C7 1 最高位没有进位 C7→out 0 ↓ V 1 ⊕ 0 1 ✅ 正确⭐ 什么时候看哪个标志// 无符号比较if(ab)→ ★ 看 C 标志// 有符号比较if(ab)→ ★ 看 V 和 N 标志汇编里的两套跳转指令无符号有符号含义JA(Above)JG(Greater)大于JB(Below)JL(Less)小于JAEJGE大于等于这是很多底层 bug 的来源★ 用错了跳转指令在数据跨过 127 或 255 边界时就会出错。十七、标志位的用途【条件跳转】 CMP A, B JZ equal ← Z1 跳 JN less ← N1 跳 【多字长运算】 ★ 64 位机器算 128 位加法 先加低 64 位 → 得到 Carry ★ 再加高 64 位时带上这个 CarryADC 指令 【溢出检测】 ★ 算术运算后检查 V 标志决定是否报错第八部分完整的 ALU十八、把所有部分组装起来┌───────────────────────────────────────────────────┐ │ ALU │ │ │ │ A ───┬────────────────────────────┐ │ │ │ │ │ │ B ───┼──────⊕ ←── SUB │ │ │ │ │ │ │ │ ↓ ↓ ↓ │ │ ┌─────────────────┐ ┌──────────────────────┐ │ │ │ ★ 加法器 │ │ 逻辑单元 │ │ │ │ 超前进位 │ │ AND OR XOR NOT │ │ │ └────────┬────────┘ └──────────┬───────────┘ │ │ │ │ │ │ │ ┌────────────────┴───────┐ │ │ │ │ ★ 桶形移位器 │ │ │ │ │ SHL SHR SAR ROL ROR │ │ │ │ └────────┬───────────────┘ │ │ │ │ │ │ └───────┬───────┘ │ │ ↓ │ │ ┌─────────────────┐ │ │ │ ★ 多路选择器 │←──── 操作码 │ │ └────────┬────────┘ │ │ │ │ │ ├──────────────→ 结果 │ │ ↓ │ │ ┌─────────────────┐ │ │ │ ★ 标志位生成 │──────→ Z N C V │ │ └─────────────────┘ │ └───────────────────────────────────────────────────┘十九、性能关键路径ALU 的速度由最长的那条路径决定★ 关键路径通常是加法器的进位链 A、B 输入 ↓ 1 门延迟 算 G、P ↓ 2 门延迟 ★ 超前进位算出所有 Ci ↓ 1 门延迟 算 Sum ↓ 1 门延迟 ★ MUX 选择输出 ↓ 结果稳定这条路径的长度直接决定了 CPU 的主频上限。★ 时钟周期必须长于关键路径的延迟否则结果还没稳定就被锁存了。二十、现代 ALU 的额外内容教科书里的 ALU 到这里就结束了但真实 CPU 里还有单元说明乘法器⭐ 用 Booth 算法 Wallace 树通常 3~5 周期除法器⭐ 最慢的操作20~40 周期浮点单元FPU独立的一套处理 IEEE 754SIMD 单元⭐ 一条指令处理多组数据SSE/AVX/NEON位操作扩展popcount数1的个数、前导零计数、位反转现代 CPU 通常有多个 ALU 并行工作。★ 比如一个核心有 4 个整数 ALU可以同时执行 4 条独立的算术指令。这叫超标量。速查表核心公式【半加器】 Sum A ⊕ B Carry A · B 【全加器】 Sum A ⊕ B ⊕ Cin Cout A·B (A⊕B)·Cin G P·Cin 【超前进位】 G A·B 生成 P A⊕B 传播 C(i1) Gi Pi·Ci 【补码】 -B ~B 1 A - B A ~B 1 【溢出】 V C(n) ⊕ C(n-1)组件对照组件作用延迟半加器两位相加1 门全加器三位相加2 门串行加法器n 位加法⭐ O(n)⭐超前进位加法器n 位加法⭐O(log n)逻辑阵列AND/OR/XOR⭐ 1 门⭐桶形移位器任意位移位⭐log₂(n) 级MUX选择输出1~2 门标志位速查标志怎么算什么时候用Z所有结果位 NOR判断相等N结果最高位判断正负⭐C最高位的进位输出⭐无符号溢出 / 多字长运算⭐VC(n) ⊕ C(n-1)⭐有符号溢出⭐ 异或在 ALU 里的四次登场位置用的是什么性质半加器的 Sum⭐ 不进位加法全加器的 Sum⭐ 三输入的奇偶性加减法切换⭐A⊕1 Ā受控取反溢出判定⭐C(n) ⊕ C(n-1)判断两者是否不同如果只能记住 ALU 里的一个门那就是异或门。收尾回到开头那个问题CPU 最核心的部件只会做二十来件事。现在把这二十来件事拆开看会发现更惊人的事实——它们全都建立在【一个全加器】上 加法 → ★ 全加器串起来 减法 → ★ 全加器 异或取反 比较 → ★ 减法只看标志位 逻辑 → ★ 单层门阵列 移位 → ★ 多路选择器网络而全加器本身只是两个异或门、两个与门、一个或门。⭐整篇文章可以压成三句话一、ALU 的复杂度不在功能多而在用一套电路实现多种功能。★ 靠的是多路选择器和受控取反。二、加法器是核心而加法器的瓶颈是进位传播。★ 超前进位用面积换速度把 O(n) 降到 O(log n)。三、Carry 和 Overflow 不是一回事。★ 一个是无符号视角的溢出一个是有符号视角的溢出——同一组比特两种解读。最后你手机里正在运行的每一行代码每一次浮点计算每一帧画面——★ 最终都落在一个只会把两个比特加起来顺便记一下要不要进位的小电路上。它一秒钟做几十亿次这件事从不出错。
企业数字化 ERP 产品动态
相关推荐
YARA Magic 模块完全指南:用 libmagic 文件类型识别能力武装你的检测规则 网络安全模式匹配 【免费下载链接】yara The pattern matching swiss knife 项目地址: https://gitcode.com/gh_mirrors/ya/yara 点击查看 免费下载 导读
Magic 模块是 YARA 提供的官方模块之一,它把 Unix 标准命令 file 背后的 libmagic 库能力直接接… · 2026/9/24 13:58:41
字节流、字符流 一、IO概述1.1 什么是IO生活中,你肯定经历过这样的场景。当你编辑一个文本文件,忘记了ctrls ,可能文件就白白编辑了。当你电脑上插入一个U盘,可以把一个视频,拷贝到你的电脑硬盘里。那么数据都是在哪些设备上的呢&… · 2026/9/24 13:58:41
Django实现异步视图adrf请求 随着现代Web开发需求的不断升级,异步编程逐渐成为了开发者关注的焦点。Django作为一个功能强大的Web框架,其默认视图是同步的,这在处理高并发请求时可能会面临一定的性能瓶颈。为了弥补这一不足,开发者可以结合Django和第三方工具,如ADRF(Async Django Rest Framework),… · 2026/9/24 13:58:41
StoryDiffusion:长序列故事图像生成工具,让多帧漫画中的角色保持一致 StoryDiffusion:长序列故事图像生成工具,让多帧漫画中的角色保持一致 【免费下载链接】StoryDiffusion Accepted as [NeurIPS 2024] Spotlight Presentation Paper 项目地址: https://gitcode.com/GitHub_Trending/st/StoryDiffusion
StoryDiffus… · 2026/9/24 14:24:32
IronClaw 能力调用膜(CapabilityHost):特权效果的单一授权入口架构解析 人工智能AI 应用交互助手AI Agent 【免费下载链接】ironclaw IronClaw is an Agent OS focused on privacy, security and extensibility 项目地址: https://gitcode.com/gh_mirrors/iro/ironclaw 点击查看 免费下载 导读
本文以 crates/kernel/ironclaw_capabili… · 2026/9/24 14:24:32
ESP32 SPI驱动W5500以太网实战:从原理到代码 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/24 14:24:26
SL651-2014实战解码:HEX报文快速定位与CRC/BCD精准解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/24 14:24:26
Visdom 安装与部署实战指南:pip 安装、源码构建、服务器启动与问题排查 数据可视化前端 【免费下载链接】visdom Tool for real-time visualization, monitoring and collaborative analysis of AI/ML experiments and live data. Supports Python, PyTorch/Torch, NumPy, TensorFlow/Keras https://visdom.dev 项目地址: https://gitcod… · 2026/9/24 14:24:13
基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程 简介:这是一套面向计算机、人工智能、自动化等专业学生与教师的毕业设计级项目资源,围绕YOLOv8实现渔船作业监控系统,可用于毕设、课程设计、大作业或项目立项演示。压缩包共97个文件,约24.21MB,以70个Python源码文件为… · 2026/9/24 0:00:13
1D-CNN时间序列建模实战:从Conv1d原理到工业落地 简介:面向时间序列数据建模的一维卷积神经网络完整实现,适合深度学习入门者及需要快速验证时序模型的研究者,能够从音频、文本、传感器或股价等序列中挖掘局部特征与时间依赖。压缩包体积很小,只有3KB,内含3个Python脚… · 2026/9/24 0:00:26
柔软的L:汉语语流中被忽视的舌肌张力控制 1. 这个“L”不是字母表里的L,而是舌尖上的L最近在几个方言群和语音教学社群里,反复看到有人发一句:“也说字母L:柔软的长舌”。初看以为是英语发音课笔记,点开才发现全是方言爱好者、播音系学生、语言康复师甚至戏曲演… · 2026/9/24 0:00:44