Menu Close

什么是 ALU?CPU 如何执行算术与逻辑运算

在前面的教程中,我们已经学习了逻辑门,也学习了半加器和全加器。

半加器可以对两个二进制位进行加法。

全加器则进一步加入了 Carry-in,也就是来自低一位的进位输入。

但是 CPU 显然不能只做一个 bit 的加法。

什么是 ALU?CPU 如何执行算术与逻辑运算

它还需要执行:

  • 加法
  • 减法
  • AND
  • OR
  • XOR
  • 比较

CPU 中负责完成大量这类运算的部件,就是 ALU

ALU 的全称是:

Arithmetic Logic Unit

中文通常称为:

算术逻辑单元

它是 CPU 中最基本、也是最重要的组成部分之一。


1. What Does an ALU Do? —— ALU 到底做什么?

从最简单的角度来看,ALU 接收两个二进制数据,对它们执行某种操作,然后产生一个结果。

例如:

输入 A
输入 B

进入 ALU 以后,可能得到:

Result

但这里马上出现一个问题:

ALU 到底应该做什么?

是把 A 和 B 相加?

还是相减?

还是做 AND?

还是做 OR?

因此,ALU 除了数据输入之外,还需要一个非常重要的输入:

ALU Control

也就是 ALU 控制信号。

它告诉 ALU:

这一次应该执行哪一种操作。

What Does an ALU Do? —— ALU 到底做什么?

因此,一个最基本的 ALU 可以理解成:

Input A + Input B + ALU Control → ALU → Result


2. Arithmetic and Logic —— 为什么叫 Arithmetic Logic Unit?

ALU 这个名字其实已经告诉了我们它最主要的功能。

它包含两类操作:

Arithmetic:算术运算

例如:

A + B

A – B

以及:

Logic:逻辑运算

例如:

A AND B

A OR B

A XOR B

除此之外,ALU 通常还可以参与数字比较。

例如:

A 是否等于 B?

A 是否小于 B?

Arithmetic and Logic —— 为什么叫 Arithmetic Logic Unit?

所以可以把 ALU 想象成一个内部包含多种功能的硬件模块:

ADD

SUB

AND

OR

XOR

COMPARE

CPU 根据当前正在执行的指令,从中选择需要的功能。


3. Addition Inside the ALU —— ALU 如何做加法?

我们前面已经学习过二进制加法。

一个 Full Adder,也就是全加器,可以接收:

A

B

Carry-in

并输出:

Sum

Carry-out

真正的 CPU 通常处理的不是一个 bit,而是:

32-bit

64-bit

甚至更宽的数据。

因此,ALU 内部的加法电路必须能够一次处理完整的二进制数字。

这一章我们不深入研究多位加法器内部究竟如何连接。

只需要先理解一个核心概念:

ALU 内部存在真正的二进制加法硬件。

例如:

A = 5

B = 3

对应二进制:

0101

0011

执行加法:

0101 + 0011 = 1000

所以:

5 + 3 = 8

Addition Inside the ALU —— ALU 如何做加法?

这里非常重要的一点是:

ALU 并不是运行一个软件程序来计算 5 + 3。

这些运算直接由数字电路完成。


4. Subtraction Inside the ALU —— ALU 如何做减法?

ALU 不仅能加,也能减。

例如:

7 – 3 = 4

但是 CPU 并不一定需要完全独立的一套减法系统。

现代计算机通常使用 Two’s Complement,也就是二进制补码 表示负数。

这样,减法就可以转换成加法。

因为:

A – B

可以写成:

A + (-B)

例如:

7 – 3

实际上可以看成:

7 + (-3)

Subtraction Inside the ALU —— ALU 如何做减法?

为了得到 -3,我们可以使用补码

以 4-bit 为例:

3 = 0011

先取反:

1100

再加 1:

1101

所以:

-3 = 1101

这样,加法硬件就可以参与完成减法。

这也是补码在计算机体系结构中如此重要的原因之一:

同一套基本算术硬件,可以同时支持正数、负数、加法和减法。


5. AND Operation —— ALU 的 AND 运算

ALU 不只是做算术。

它还可以直接执行 Boolean Logic,也就是布尔逻辑运算。

先看 AND。

AND 的规则非常简单:

0 AND 0 = 0

0 AND 1 = 0

1 AND 0 = 0

1 AND 1 = 1

只有两个输入都是 1,结果才是 1。

例如:

A = 1100

B = 1010

执行 AND:

1100 AND 1010 = 1000

AND Operation —— ALU 的 AND 运算

这里的 AND 并不是把整个数字作为一个整体判断。

它是:

逐 bit 运算。

最左边的一位和最左边的一位做 AND。

下一位和下一位做 AND。

一直到最低位。

这种操作在计算机中非常常见,例如可以用于:

Bit Masking,位掩码。


6. OR Operation —— ALU 的 OR 运算

OR 的规则是:

只要两个输入中至少有一个是 1,输出就是 1。

也就是:

0 OR 0 = 0

0 OR 1 = 1

1 OR 0 = 1

1 OR 1 = 1

例如:

A = 1100

B = 1010

那么:

1100 OR 1010 = 1110

【图 6:OR Operation】

和 AND 一样,OR 也是逐 bit 进行的。

因此一个 32-bit ALU 可以同时对 32 对 bit 进行 OR 运算。


7. XOR Operation —— ALU 的 XOR 运算

XOR 是 Exclusive OR,也就是异或。

它的特点是:

两个 bit 不同,输出 1。

两个 bit 相同,输出 0。

因此:

0 XOR 0 = 0

0 XOR 1 = 1

1 XOR 0 = 1

1 XOR 1 = 0

例如:

A = 1100

B = 1010

执行 XOR:

1100 XOR 1010 = 0110

【图 7:XOR Operation】
【图 7:XOR Operation】

其实 XOR 我们已经见过。

在 Half Adder,也就是半加器里面:

Sum = A XOR B

所以从这里也可以看到:

ALU 并不是一个完全陌生的新东西。

它使用的很多基本逻辑,其实都来自我们前面学习过的逻辑门。


8. How Does the ALU Know What to Do? —— ALU 怎么知道应该做什么?

现在假设 ALU 收到两个数字:

A = 5

B = 3

那么问题来了:

它应该输出什么?

可能是:

5 + 3

也可能是:

5 – 3

还可能是:

5 AND 3

或者:

5 OR 3

所以,只有 A 和 B 两个输入还不够。

ALU 还必须得到:

ALU Control

How Does the ALU Know What to Do? —— ALU 怎么知道应该做什么?

我们可以用一个简单的例子理解:

000 → AND

001 → OR

010 → ADD

110 → SUB

111 → COMPARE

注意:

不同 CPU 的编码并不一定完全一样。

这里真正需要理解的是:

ALU Control 是用来选择 ALU 操作的。

换句话说:

数据告诉 ALU “对什么进行运算”。

控制信号告诉 ALU “进行什么运算”。


9. Where Do the ALU Inputs Come From? —— ALU 的数据从哪里来?

ALU 自己并不负责长期保存数据。

在很多 CPU 指令中,ALU 的输入来自:

Registers,也就是寄存器。

例如:

Register A

Register B

把两个值送进 ALU。

ALU 完成计算以后,再产生 Result。

【图 9:Where Do the ALU Inputs Come From?】
【图 9:Where Do the ALU Inputs Come From?】

这也是为什么我们前面专门学习 Register File。

因为寄存器和 ALU 是紧密联系在一起的。

寄存器负责:

保存 CPU 当前正在使用的数据。

ALU 负责:

处理这些数据。


10. The ALU and the Register File —— ALU 与寄存器文件

如果把 Register File 和 ALU 放在一起看,CPU 的基本数据流就开始变得非常清楚了。

Register File 中保存着:

R0

R1

R2

……

R31

假设 CPU 需要使用其中两个寄存器。

Register File 可以通过两个读端口:

Read Port A

Read Port B

同时读取两个操作数

然后把它们送到 ALU。

【图 10:The ALU and the Register File】

流程可以简单理解为:

Register File

→ Read A / Read B

→ ALU

→ Result

→ Write Back

→ Register File

这实际上已经是 CPU datapath,也就是 CPU 数据通路中非常核心的一部分。


11. Example: ADD Instruction —— 一个 ADD 指令到底发生了什么?

现在来看一个具体例子。

假设有这样一条指令:

ADD R1, R2, R3

它的意思是:

R1 = R2 + R3

假设:

R2 = 5

R3 = 3

CPU 首先从 Register File 中读取:

R2 = 5

R3 = 3

然后把两个值送进 ALU。

ALU Control 告诉 ALU:

ADD

于是 ALU 执行:

5 + 3 = 8

最后:

R1 = 8

【图 11:Example: ADD Instruction】

整个过程可以概括成四步:

第一步:

Read R2

第二步:

Read R3

第三步:

ALU ADD

第四步:

Write R1

这张图其实把前面我们讲过的:

Register File

和现在讲的:

ALU

真正连接起来了。


12. Example: AND Instruction —— AND 指令也是同一条数据通路

现在把 ADD 换成 AND。

假设指令是:

AND R1, R2, R3

Register File 的工作并没有发生本质变化。

仍然是:

读取 R2

读取 R3

然后把它们送到 ALU。

不同的是:

这一次 ALU Control 不再告诉 ALU:

ADD

而是告诉它:

AND

于是 ALU 对两个寄存器中的数据进行逐 bit AND。

所以我们会发现一个非常重要的特点:

数据通路可以基本不变。

变化的主要是:

ALU Control。

也就是说,同一个 ALU 可以执行许多不同类型的指令。


13. Comparisons —— ALU 还可以参与比较

程序除了计算之外,还要不断做判断。

例如:

A == B

A < B

A > B

这些比较对于程序控制非常重要。

例如:

if A == B

那么 CPU 就必须判断:

A 和 B 到底是不是相等。

ALU 可以参与完成这种比较。

一个非常容易理解的方法是:

计算:

A – B

如果:

A – B = 0

那么就说明:

A = B

所以加法、减法和比较,其实并不是完全彼此独立的世界。

它们在 CPU 硬件中有着非常紧密的联系。


14. ALU Status Outputs —— ALU 不只输出 Result

ALU 除了产生最终计算结果以外,还可能产生一些额外的状态信息。

常见的包括:

Zero

Carry

Overflow

Negative

例如:

Zero

表示 ALU 的计算结果是不是 0。

假设 CPU 执行:

A – B

如果结果是:

0

那么:

A = B

因此 Zero 信号可以帮助 CPU 判断某些条件。

Carry

通常和无符号运算中的进位有关。

Overflow

通常和有符号整数运算超出表示范围有关。

Negative

可以用来反映结果是否为负数。

不过不同 CPU 架构处理这些状态信息的方法并不完全一样。

在这一篇入门教程中,只需要记住:

ALU 可能同时输出:

Result + Status Information

即可。


15. The ALU Is Not the Entire CPU —— ALU 并不是整个 CPU

ALU 很重要。

但 ALU 绝对不是 CPU 的全部。

CPU 中还有许多其它组成部分。

例如:

Register File

Instruction Decoder

Control Unit

Cache

Bus

以及其它数据通路和控制逻辑。

【图 12:ALU in the CPU — Big Picture】

从整体上看:

Register File

负责提供数据。

ALU

负责对数据进行运算。

Instruction Decoder

负责理解当前指令是什么。

Control Unit

负责产生各种控制信号。

其它部分则负责数据移动、存储访问以及 CPU 内部的协调。

因此:

ALU 是 CPU 的执行核心之一,但它必须和其它硬件一起工作。


16. From Logic Gates to the ALU —— 从逻辑门一路走到 ALU

现在我们可以把前面几篇教程真正串起来了。

一开始,我们学习的是最简单的:

AND

OR

XOR

NOT

这些都是 Logic Gates,也就是逻辑门。

然后,我们发现:

逻辑门可以组成更加复杂的电路。

例如:

Half Adder

半加器。

继续组合以后,就得到:

Full Adder

全加器。

现在我们又向上走了一层。

这些算术电路和逻辑电路共同构成:

ALU

然后 ALU 再和:

Register File

Control Unit

Instruction Decoder

Cache

Bus

等硬件连接起来。

最终形成 CPU

所以可以把整个过程理解成:

Logic Gates

Arithmetic and Logic Circuits

ALU

CPU

这也是理解计算机体系结构最重要的一条主线:

复杂的 CPU,并不是凭空出现的。

它最终仍然是由大量简单数字电路一步一步组合起来的。


17. Conclusion —— 总结

ALU,Arithmetic Logic Unit,也就是算术逻辑单元,是 CPU 中负责执行大量算术和逻辑运算的重要硬件。

它可以执行的典型操作包括:

ADD

SUB

AND

OR

XOR

COMPARE

ALU 通常接收两个输入数据。

这些数据很多时候来自 CPU 的 Register File。

然后:

ALU Control

告诉 ALU 应该执行哪一种操作。

ALU 完成运算以后产生:

Result

并可能同时产生:

Zero

Carry

Overflow

Negative

等状态信息。

整个过程可以简单理解为:

Registers

ALU

Result

Registers

这就把我们前面学习过的许多知识真正连接了起来。

我们从:

Logic Gates

开始。

然后学习:

Half Adder

Full Adder

现在进一步进入:

ALU

也就是说,我们正在从最基本的数字逻辑,一步一步走向真正的 CPU

而接下来的一个非常自然的问题就是:

CPU 是怎么知道当前应该让 ALU 做 ADD、SUB、AND,还是其它操作的?

这就会把我们带到 CPU 的另一个核心部分:

Instruction Decoding 和 Control Unit。

Posted in CPU结构