跳到正文

王道计算机组成原理第一章补充讲义

王道《计算机组成原理》第一章补充讲义

参考教材:

  • 唐朔飞《计算机组成原理》第3版
  • 袁春风、唐杰、杨若瑜《计算机组成与系统结构》第3版

一、从“抽象层次”理解计算机系统

1. 为什么计算机系统要分层?

计算机硬件只能直接识别机器指令,但程序员通常使用高级语言。

例如我们写:

c = a + b;

CPU 并不能直接理解这条 C 语句,它需要经过多层转换:

\[\boxed{ \text{实际问题} \rightarrow \text{算法} \rightarrow \text{高级语言程序} \rightarrow \text{汇编语言程序} \rightarrow \text{机器指令} \rightarrow \text{控制信号} \rightarrow \text{数字逻辑电路} } \]

每一层向上一层提供一个更容易使用的接口,同时隐藏下一层的实现细节,这就是:

\[\boxed{\text{抽象}} \]

例如,C 语言程序员只需要使用加法运算,不必考虑 CPU 内部的加法器采用串行进位还是并行进位。

2. 什么叫“虚拟机器”?

唐朔飞教材把每一个语言层次看成一台“虚拟机器”。

层次 使用的语言或接口 实现方式
高级语言机器 C、C++ 等 编译程序或解释程序
汇编语言机器 汇编指令 汇编程序
操作系统机器 系统调用 操作系统
机器语言机器 机器指令 CPU 硬件
微程序机器 微指令 控制器
数字逻辑层 门电路、触发器 电子器件

这里的“虚拟机器”不是特指 VMware、VirtualBox,而是指:

通过软件或下层机器提供功能,使用户感觉自己在使用一台功能更强、更方便的机器。

3. 翻译与解释的区别

翻译

先把源程序整体转换为低一级语言的程序,再执行转换后的程序。

\[\boxed{ \text{源程序} \xrightarrow{\text{翻译}} \text{目标程序} \xrightarrow{\text{执行}} \text{结果} } \]

编译程序和汇编程序都属于翻译程序。

解释

逐条分析源程序,并立即执行对应功能,通常不生成完整的目标程序。

\[\boxed{ \text{取一条源语句} \rightarrow \text{解释} \rightarrow \text{执行} } \]

易错点:操作系统层的功能通常不是简单的“翻译”,而是通过系统调用、内核程序等方式实现。因此,计算机层次结构并不全是语言逐层翻译。


二、ISA、计算机组成和微体系结构

1. ISA 是什么?

ISA,即指令集体系结构,是软件和硬件之间的接口:

\[\boxed{ \text{软件} \longleftrightarrow \text{ISA} \longleftrightarrow \text{硬件} } \]

ISA 规定程序员能够看见的计算机属性,主要包括:

  • 指令系统;
  • 指令格式;
  • 操作数类型;
  • 寻址方式;
  • 程序可访问的寄存器;
  • 地址空间大小;
  • 中断和异常机制;
  • I/O 编址方式;
  • 存储保护方式;
  • 机器工作状态。

因此:

\[\boxed{\text{ISA 属于软件可见部分}} \]

2. 计算机体系结构与计算机组成

计算机体系结构

指程序员能够看到的属性,即计算机“能够提供什么功能”。

例如:

  • 是否有乘法指令;
  • 有多少个程序可访问寄存器;
  • 指令采用什么格式;
  • 支持哪些数据类型和寻址方式。

计算机组成

指这些属性在硬件中如何实现,即计算机“怎样实现这些功能”。

例如:

  • 乘法采用专门乘法器,还是由加法器和移位器完成;
  • 控制器采用硬布线还是微程序;
  • Cache 容量多大;
  • 总线采用什么连接方式。
问题 所属内容
是否存在乘法指令 体系结构 / ISA
乘法指令如何在硬件中实现 计算机组成
有多少个通用寄存器 体系结构 / ISA
寄存器采用什么电路实现 计算机组成
是否支持中断 体系结构 / ISA
中断控制器如何设计 计算机组成

3. ISA 与微体系结构

微体系结构是 ISA 的一种具体硬件实现。

同一种 ISA 可以有不同的微体系结构,例如不同代的 x86 处理器:

  • 都能执行 x86 指令;
  • 内部流水线、Cache、执行单元、分支预测等可能完全不同;
  • 性能和功耗也不同。

因此:

\[\boxed{ \text{相同 ISA} \not\Rightarrow \text{相同内部结构和性能} } \]

但通常具有较好的机器程序兼容性。

4. 透明性的含义

“某个事物对某类用户透明”表示:

这个事物实际存在,但该类用户看不见,也不需要关心。

例如:

  • 高级语言程序员通常看不见机器指令编码;
  • 应用程序员通常看不见操作系统如何调度 CPU;
  • 程序员通常看不见加法器内部的门电路。

注意:

\[\boxed{\text{透明不是不存在,而是对某类用户不可见}} \]

而且透明性必须说明“对谁透明”。


三、现代计算机硬件的实际组成

1. 五大部件与现代结构的对应关系

冯·诺依曼计算机的五大部件是:

\[\boxed{ \text{运算器、控制器、存储器、输入设备、输出设备} } \]

在现代计算机中可以重新归纳为:

\[\boxed{ \text{计算机硬件} = \text{CPU} + \text{主存} + \text{I/O 模块} + \text{外部设备} + \text{总线} } \]

其中:

\[\boxed{ \text{CPU} = \text{数据通路} + \text{控制器} } \]

数据通路通常包含:

  • ALU;
  • 通用寄存器组;
  • 内部总线;
  • 移位器等数据处理部件。

所以不能机械地认为现代 CPU 内部只有“运算器和控制器”。

2. 主机不等于机箱

计算机组成原理中的“主机”通常指:

\[\boxed{\text{主机}=\text{CPU}+\text{主存}} \]

外部设备通常不属于主机。这里的“主机”不是日常生活中所说的电脑机箱。

3. I/O 设备一般不直接连接 CPU

现代计算机中,外部设备通常通过设备控制器连接到系统中:

\[\boxed{ \text{外部设备} \longleftrightarrow \text{设备控制器} \longleftrightarrow \text{总线} \longleftrightarrow \text{CPU/主存} } \]

外部设备 对应控制器
显示器 显示控制器、显卡
键盘、鼠标 USB 控制器
磁盘 磁盘控制器
网络设备 网络控制器、网卡

设备本身与设备控制器不是完全相同的概念。

4. 以运算器为中心与以存储器为中心

早期冯·诺依曼计算机以运算器为中心,输入输出设备与存储器之间交换数据时也要经过运算器,容易造成运算器负担过重。

现代计算机通常以存储器为中心:

\[\boxed{ \text{CPU、I/O 设备通过总线与主存交换信息} } \]

这样可以减少大量数据都经过运算器造成的瓶颈。


四、存储程序思想的准确理解

存储程序思想不只是“程序放进存储器”,而是包括三个要点:

  1. 程序和数据在执行前存入主存;
  2. 指令和数据都使用二进制表示并按地址访问;
  3. CPU 能够根据程序自动、连续地取出并执行指令。

因此:

\[\boxed{ \text{存储程序} = \text{预先存储} + \text{按地址访问} + \text{自动执行} } \]

指令和数据如何区分?

指令与数据在主存中的形式可能完全相同,都是二进制代码。CPU 主要根据访问它们的时机和流向进行区分。

取指阶段

\[PC\rightarrow MAR\rightarrow\text{主存}\rightarrow MDR\rightarrow IR \]

从 PC 给出的地址取出的内容进入 IR,因此被 CPU 解释为指令。

执行阶段

指令中的地址码或计算出的有效地址送入 MAR,从主存取出的内容通常作为操作数使用。

因此:

\[\boxed{ \text{进入 IR 的内容被解释为指令,作为操作对象读取的内容被解释为数据} } \]

严格来说,区分依据是 CPU 当前执行过程以及信息所进入的部件,而不是二进制代码本身。


五、程序从源代码到执行的完整过程

以 C 语言程序为例:

flowchart TD A["hello.c 源程序"] --> B["预处理"] B --> C["hello.i"] C --> D["编译"] D --> E["hello.s 汇编程序"] E --> F["汇编"] F --> G["hello.o 可重定位目标文件"] G --> H["链接"] H --> I["可执行文件"] I --> J["装入主存并执行"]

1. 预处理

处理以 # 开头的命令,例如:

  • #include
  • #define
  • 条件编译

结果仍是高级语言文本。

2. 编译

将预处理后的高级语言程序翻译为汇编语言程序:

\[\text{高级语言}\rightarrow\text{汇编语言} \]

3. 汇编

将汇编程序翻译成机器代码,生成可重定位目标文件:

\[\text{汇编语言}\rightarrow\text{机器指令} \]

但此时一些地址可能还没有最终确定。

4. 链接

将多个目标文件以及库函数合并,解决模块间的符号引用,生成可执行文件。

例如程序调用 printf(),链接器要把程序与相应库代码联系起来。

5. 装入与执行

可执行文件平时存放在磁盘中,不能直接被 CPU 执行。操作系统装入程序负责:

  1. 将程序的代码和数据装入主存;
  2. 建立程序运行所需的存储空间;
  3. 将程序入口地址送入 PC;
  4. CPU 开始取指执行。

因此:

\[\boxed{ \text{可执行文件生成后仍不能直接在磁盘上执行,必须先装入主存} } \]


六、一条指令的完整执行过程

1. 重要寄存器

寄存器 作用
PC 存放下一条将要执行的指令地址
IR 存放当前正在执行的指令
MAR 存放当前要访问的主存地址
MDR 存放从主存读出的或准备写入主存的数据
ACC 累加器,存放操作数或运算结果
GPRs 通用寄存器组,存放操作数、地址和结果
标志寄存器 存放零、进位、负数、溢出等状态

2. 取指

\[PC\rightarrow MAR \]

CPU 发出主存读命令:

\[M(MAR)\rightarrow MDR \]

然后:

\[MDR\rightarrow IR \]

同时,PC 形成顺序执行时下一条指令的地址:

\[\boxed{ PC\leftarrow PC+\text{当前指令长度} } \]

唐朔飞模型机中一条指令占一个存储字,所以写成 \(PC+1\)。现实机器中不一定是加 1。

3. 译码

控制器分析 IR 中的操作码:

\[OP(IR)\rightarrow CU \]

控制器由此判断:

  • 做什么操作;
  • 从哪里取操作数;
  • 结果送到哪里;
  • 需要发出哪些控制信号。

4. 取操作数并执行

如果操作数在主存中:

\[Ad(IR)\rightarrow MAR \]

\[M(MAR)\rightarrow MDR \]

再将操作数送入寄存器或 ALU 进行运算。

5. 写回结果

运算结果可能写入:

  • 通用寄存器;
  • ACC;
  • 主存;
  • PC;
  • 状态寄存器。

概括为:

\[\boxed{ \text{取指} \rightarrow \text{译码} \rightarrow \text{取操作数} \rightarrow \text{执行} \rightarrow \text{写回} } \]


七、程序不一定严格顺序执行

“指令通常顺序存放”不等于“永远顺序执行”。

正常情况下:

\[PC\leftarrow PC+\text{指令长度} \]

但遇到以下情况时,PC 可能被重新赋值:

  • 无条件转移;
  • 条件分支;
  • 函数调用;
  • 函数返回;
  • 中断和异常。

所以更准确地说:

CPU 按照 PC 指出的地址取指,而 PC 通常顺序变化,也可能因转移等原因被修改。


八、算法也会影响计算机性能

唐朔飞教材用计算

\[ax^2+bx+c \]

说明同一个数学问题可以采用不同算法。秦九韶形式为:

\[(ax+b)x+c \]

第二种形式减少了乘法次数。

这说明程序执行时间不仅由硬件决定,还受算法、编程语言和编译器影响:

\[\boxed{ \text{问题} \rightarrow \text{算法} \rightarrow \text{程序} \rightarrow \text{指令序列} \rightarrow \text{CPU 执行时间} } \]

因此,性能公式中的指令条数 \(IC\) 不是固定不变的,它受到以下因素影响:

  • 算法;
  • 编程语言;
  • 编译器;
  • ISA。

九、执行时间要区分不同口径

1. 响应时间

从任务提交到任务完成的总时间,可能包括:

  • 用户程序的 CPU 时间;
  • 操作系统运行时间;
  • I/O 等待时间;
  • 等待 CPU 调度的时间;
  • 其他系统开销。

2. 用户 CPU 时间

CPU 真正用于执行该用户程序代码的时间。

王道中的公式:

\[T_{\mathrm{CPU}} = \frac{IC\times CPI}{f} \]

通常计算的是:

\[\boxed{\text{用户 CPU 执行时间}} \]

不一定等于用户实际感受到的总响应时间。

例如,一个程序 CPU 只计算 1 秒,但等待磁盘 9 秒:

\[T_{\text{CPU}}=1\text{s} \]

\[T_{\text{响应}}=10\text{s} \]


十、性能三因素相互制约

CPU 时间为:

\[\boxed{ T_{\mathrm{CPU}} = IC\times CPI\times T = \frac{IC\times CPI}{f} } \]

其中:

  • \(IC\):执行的指令条数;
  • \(CPI\):平均每条指令使用的时钟周期数;
  • \(T\):时钟周期;
  • \(f\):主频。

不能单独通过其中一个指标判断性能。例如:

  • 提高主频可能导致流水线更深,从而使 CPI 增大;
  • 复杂指令可能减少 \(IC\),但增大 CPI;
  • 简化指令可能降低 CPI,却需要更多指令。

所以最终判断依据是:

\[\boxed{T_{\mathrm{CPU}}} \]


十一、基准程序的正确使用

只比较主频、CPI 或 MIPS 都不够准确。

更可靠的方法是:

在不同机器上运行相同且有代表性的实际程序,比较其执行时间。

常见基准包括:

  • SPEC:通用处理器性能测试;
  • LINPACK:浮点计算与高性能计算测试。

如果测试集中有多个程序,可以使用:

  • 执行时间算术平均值;
  • 执行时间几何平均值;
  • 按程序使用频率进行加权平均。

但必须保证测试负载具有代表性。


十三、三本教材结合后必须掌握的结论

  1. 计算机系统是一个层次化的抽象系统。
  2. ISA 是软件与硬件之间的接口,属于软件可见部分。
  3. 计算机体系结构研究“提供什么功能”,计算机组成研究“如何实现”。
  4. 同一 ISA 可以采用不同微体系结构实现。
  5. “透明”表示某部分存在,但对特定用户不可见。
  6. 现代 CPU 由数据通路和控制器组成,不只有 ALU 和 CU。
  7. 计算机组成原理中的主机通常是 CPU 和主存,而不是机箱。
  8. 外设一般通过设备控制器和总线与主机交换信息。
  9. 存储程序包括预先存储、按地址访问和自动执行。
  10. 指令与数据形式上没有区别,CPU 根据执行阶段和信息流向区分。
  11. 高级语言程序一般经历预处理、编译、汇编、链接和装入才能执行。
  12. PC 保存下一条要执行的指令地址;顺序执行时增加一条指令的长度,而不一定恒为 1。
  13. 一条指令通常经历取指、译码、取操作数、执行和写回。
  14. CPU 时间不一定等于用户感受到的响应时间。
  15. 指令条数、CPI 和主频相互制约,必须综合比较执行时间。
posted @ 2026-08-04 20:01  尔一  阅读(44)  评论(0)    收藏  举报