05

计算机体系结构

把一切组装起来

阅读量:7 · 预计 10 分钟读完

CPU设计总线存储映射
阅读进度5%

第五章 计算机体系结构

导读

前四章我们构建了计算机的所有硬件组件:逻辑门、ALU、寄存器和内存,并学习了机器语言编程。本章将把这些组件整合在一起,构建一台完整的计算机——Hack计算机。

计算机体系结构是计算机科学的基石。理解计算机体系结构不仅帮助我们理解计算机如何工作,还培养了系统化设计复杂工程系统的能力。本章将展示如何通过精心设计的架构,将简单的组件组合成功能强大的计算系统。

通过本章的学习,你将理解计算机各组件如何协同工作,掌握计算机体系结构的设计原则,并亲手构建一台完整的计算机。这是从硬件到软件的关键桥梁,也是理解整个计算机系统的基础。

核心概念详解

5.1 冯·诺依曼架构

Hack计算机基于经典的冯·诺依曼架构,其核心特点是:

存储程序概念

程序和数据存储在同一内存中,可以被同等对待。这意味着:

  • 程序可以像数据一样被处理
  • 程序可以修改自身(自修改代码)
  • 简化了硬件设计

五大组件

冯·诺依曼架构包含五个基本组件:

运算器(ALU):执行算术和逻辑运算

控制器(Control Unit):协调各组件工作,控制指令执行

存储器(Memory):存储程序和数据

输入设备(Input):接收外部输入

输出设备(Output):向外部输出结果

在Hack计算机中,这些组件通过系统总线连接,形成一个完整的计算系统。

5.2 Hack计算机架构

Hack计算机是一个16位计算机,具有以下特性:

硬件组成

Hack计算机 = ALU + 寄存器 + 内存 + 控制逻辑

具体包括:

  • ALU:16位算术逻辑单元
  • 寄存器:D寄存器、A寄存器
  • 内存:统一的16位内存空间,包括RAM、屏幕内存和键盘内存
  • 程序计数器(PC):15位程序计数器
  • 控制逻辑:解码指令并控制各组件工作

内存映射

Hack计算机的内存空间分为三个区域:

RAM(0-16383)

- 24K字的通用内存

- 用于存储程序和数据

- 包括变量、数组、堆栈等

屏幕内存(16384-24575)

- 8K字的内存

- 映射到512×256像素的黑白屏幕

- 每个字控制32个水平像素

键盘内存(24576)

- 1个字的内存

- 映射到键盘

- 存储当前按下的键的ASCII码

指令执行流程

Hack计算机的指令执行遵循以下步骤:

取指:PC提供地址,从内存读取指令

解码:控制单元解码指令,确定操作类型

执行

- A指令:将值加载到A寄存器

- C指令:控制ALU执行操作,存储结果,可能跳转

更新PC:如果跳转,PC=A;否则PC递增

重复:回到步骤1

5.3 CPU设计

CPU(中央处理单元)是计算机的核心,负责执行指令。

CPU的功能

CPU需要完成以下任务:

从内存获取指令

解码指令

执行指令

更新程序计数器

CPU的内部结构

Hack CPU包含以下组件:

  • ALU:执行算术和逻辑运算
  • D寄存器:存储操作数
  • A寄存器:存储地址/操作数
  • 控制逻辑:解码指令并控制各组件

CPU的工作原理

CPU根据当前指令类型执行不同的操作:

A指令执行

将指令的低15位加载到A寄存器

不执行ALU操作

不存储结果

不跳转

PC递增

C指令执行

根据a字段选择ALU的y输入(A或M)

根据c字段设置ALU控制信号

ALU执行计算

根据d字段存储结果到D、A或M

根据j字段和ALU输出决定是否跳转

如果跳转,PC=A;否则PC递增

5.4 内存设计

Hack计算机使用统一的内存空间,包括RAM、屏幕和键盘。

RAM设计

Hack RAM由多个层次的RAM芯片组成:

  • RAM8:8个寄存器
  • RAM64:8个RAM8
  • RAM512:8个RAM64
  • RAM4K:8个RAM512
  • RAM16K:4个RAM4K

最终构建24K RAM(地址0-16383)。

屏幕内存

屏幕内存是8K RAM(地址16384-24575):

  • 直接映射到屏幕显示
  • 每个内存字对应32个像素
  • 写入内存立即反映到屏幕

键盘内存

键盘内存是1个字的内存(地址24576):

  • 只读内存
  • 存储当前按下的键
  • 硬件自动更新

5.5 计算机集成

将所有组件集成在一起形成完整的计算机。

组件连接

CPU <--> 内存
 |        |
 |        +-- RAM (0-16383)
 |        +-- 屏幕 (16384-24575)
 |        +-- 键盘 (24576)
 |
 +-- 控制逻辑

信号流

地址信号:从PC或A寄存器到内存

数据信号:双向在CPU和内存之间

控制信号:从控制单元到各组件

读写信号:控制内存读写操作

5.6 计算机工作过程

理解计算机的工作过程对于编写高效程序至关重要。

启动过程

PC初始化为0

从地址0开始取指

执行第一条指令

继续执行后续指令

指令循环

计算机不断重复取指-执行循环,直到遇到停机指令或断电。

中断处理

虽然Hack计算机没有实现中断机制,但实际计算机通常支持中断:

  • 外部设备可以请求CPU注意
  • CPU暂停当前程序,执行中断处理程序
  • 处理完成后恢复原程序

5.7 性能考虑

计算机性能受多个因素影响。

时钟频率

时钟频率决定了指令执行的速度。更高的频率意味着更快的执行速度,但也带来功耗和散热问题。

指令周期

每条指令需要一定数量的时钟周期:

  • 简单指令:1个周期
  • 复杂指令:多个周期

内存访问

内存访问通常是性能瓶颈:

  • 内存速度远慢于CPU速度
  • 使用高速缓存缓解
  • 优化内存访问模式

流水线

现代CPU使用流水线技术提高性能:

  • 将指令执行分为多个阶段
  • 不同指令的不同阶段可以并行执行
  • 提高指令吞吐量

重要知识点

知识点1:哈佛架构vs冯·诺依曼架构

冯·诺依曼架构

  • 程序和数据共享同一内存
  • 简化硬件设计
  • 可能存在冯·诺依曼瓶颈

哈佛架构

  • 程序和数据使用独立内存
  • 可以同时访问程序和数据
  • 硬件设计更复杂

现代计算机通常采用改进的哈佛架构,在缓存级别分离程序和数据。

知识点2:总线设计

总线是连接计算机各组件的通信通道:

数据总线:传输数据,宽度决定一次传输的数据量

地址总线:传输地址,宽度决定可寻址的内存空间

控制总线:传输控制信号

知识点3:存储层次

现代计算机使用多级存储层次:

  • 寄存器:最快,容量最小
  • L1缓存:较快,容量较小
  • L2/L3缓存:较慢,容量较大
  • 主存(RAM):慢,容量大
  • 辅存(磁盘):最慢,容量最大

知识点4:指令流水线

流水线将指令执行分为多个阶段:

取指(IF):从内存获取指令

解码(ID):解码指令

执行(EX):执行操作

访存(MEM):访问内存

写回(WB):写回结果

流水线可以提高指令吞吐量,但需要处理数据冒险和控制冒险。

知识点5:并行处理

现代计算机使用多种并行技术:

  • 指令级并行:同时执行多条指令
  • 数据级并行:同时处理多个数据
  • 任务级并行:同时执行多个任务

常见误区

误区1:认为计算机一次只能做一件事

实际上,现代计算机通过流水线、多核等技术可以同时执行多个操作。但在Hack计算机中,确实是顺序执行的。

误区2:忽视内存访问延迟

内存访问比CPU操作慢得多。频繁访问内存会严重影响性能。优化内存访问模式是编写高效程序的关键。

误区3:认为更大的寄存器文件总是更好

更大的寄存器文件增加了硬件复杂度和访问延迟。需要在寄存器数量和使用便利性之间取得平衡。

误区4:不理解控制单元的作用

控制单元是CPU的"大脑",负责解码指令并控制各组件工作。没有控制单元,CPU无法正确执行指令。

误区5:认为计算机架构是一成不变的

计算机架构在不断演进。从单核到多核,从顺序执行到并行处理,架构设计在不断发展。

实践应用

实践1:实现CPU

hdl
CHIP CPU {
    IN inM[16], instruction[16], reset;
    OUT outM[16], writeM, addressM[15];
    
    PARTS:
    // A指令处理
    // 如果是A指令,将指令低15位加载到A寄存器
    // 如果是C指令,根据指令字段控制ALU
    
    // 1. 解码指令
    // instruction[15] = 0: A指令
    // instruction[15] = 1: C指令
    
    // 2. A寄存器控制
    Mux16(a=aluOut, b=instruction, sel=notC, out=aIn);
    Mux(a=dOut, b=true, sel=notC, out=aLoad);
    Register(in=aIn, load=aLoad, out=aOut);
    
    // 3. D寄存器
    Register(in=aluOut, load=dLoad, out=dOut);
    
    // 4. ALU控制
    // 根据C指令字段设置ALU
    
    // 5. PC控制
    // 根据跳转条件和ALU输出控制PC
}

实践2:实现内存

hdl
CHIP Memory {
    IN in[16], load, address[15];
    OUT out[16];
    
    PARTS:
    // 地址解码
    // address < 16384: RAM
    // 16384 <= address < 24576: 屏幕
    // address = 24576: 键盘
    
    // RAM访问
    RAM16K(in=in, load=ramLoad, address=address[0..13], out=ramOut);
    
    // 屏幕访问
    Screen(in=in, load=screenLoad, address=address[0..12], out=screenOut);
    
    // 键盘访问(只读)
    Keyboard(out=keyboardOut);
    
    // 输出选择
    Mux16(a=ramOut, b=screenOut, sel=screenSel, out=m1);
    Mux16(a=m1, b=keyboardOut, sel=keyboardSel, out=out);
}

实践3:实现完整的计算机

hdl
CHIP Computer {
    IN reset;
    
    PARTS:
    // 连接CPU和内存
    CPU(inM=memoryOut, instruction=instruction, reset=reset,
        outM=cpuOut, writeM=write, addressM=address);
    
    Memory(in=cpuOut, load=write, address=address, out=memoryOut);
    
    // 指令就是内存输出
    instruction = memoryOut;
}

实践4:测试计算机

测试完整的计算机需要加载程序并验证执行结果:

// 加载程序到内存
load RAM16K, file=program.hack;

// 运行计算机
tick, tock;
tick, tock;
// ...

// 验证结果
// 检查特定内存位置的值

实践5:编写测试程序

编写简单的测试程序验证计算机功能:

// 程序:计算1+2+...+10
@10
D=A
@0
M=0
(LOOP)
@0
D=D+M
M=D
@1
D=M-1
M=D
@1
D=M
@LOOP
D;JGT
@END
0;JMP
(END)
@END
0;JMP

实践6:性能分析

分析程序性能:

  • 计算指令数量
  • 估算执行时间
  • 识别性能瓶颈
  • 优化关键代码

本章小结

本章我们将所有硬件组件整合在一起,构建了完整的Hack计算机。

核心要点回顾

冯·诺依曼架构:存储程序概念,五大组件协同工作。

Hack架构:16位计算机,统一内存空间,简单的指令集。

CPU设计:包含ALU、寄存器和控制逻辑,负责执行指令。

内存设计:统一的内存空间,包括RAM、屏幕和键盘。

计算机集成:将所有组件连接成完整的系统。

工作过程:取指-执行循环,不断重复直到停机。

关键技能掌握

  • 理解冯·诺依曼架构的原理
  • 掌握Hack计算机的架构设计
  • 理解CPU的工作原理
  • 掌握内存映射I/O的概念
  • 能够分析和优化计算机性能

与后续章节的联系

本章构建的计算机是后续章节的基础:

  • 第六章将构建汇编器,将汇编语言转换为机器语言
  • 第七章和第八章将介绍虚拟机,提供更高级的抽象
  • 后续章节将在此基础上构建完整的软件栈

学习建议

理解整体架构:从宏观角度理解计算机各组件如何协同工作

关注细节:深入理解每个组件的工作原理

动手实践:亲手构建和测试计算机

思考设计决策:理解为什么这样设计,有什么优缺点

通过本章的学习,你已经完成了一台完整计算机的构建。从最基本的逻辑门到完整的计算机系统,这是一个了不起的成就。这台计算机虽然简单,但它包含了现代计算机的所有基本概念。理解这台计算机的工作原理,为理解更复杂的计算机系统奠定了坚实基础。

现在,我们有了硬件平台,下一步是让它更容易编程。直接编写机器语言非常繁琐,第六章我们将构建汇编器,使编程变得更加容易。