第一部分:计算机系统概述

1.1 计算机系统的层次结构

计算机系统不是单一的一层,而是像一座金字塔,从最底层的硬件到最上层的用户程序,一层层抽象和封装。理解这个层次结构,有助于你理解软件和硬件是如何分工合作的。

为什么要分层? 每一层都隐藏下层的实现细节,向上层提供更简单的服务。比如你用Python写程序,不需要知道CPU内部是如何执行指令的,因为Python解释器帮你处理了这些底层细节。

层次结构(从低到高)

  1. 微程序层(最底层,硬件实现)

    • 这是真正的硬件电路层,由逻辑门、触发器等构成。
    • 微程序实际上是一组微指令,直接控制寄存器和ALU等硬件部件。
    • 对程序员(包括汇编程序员)几乎不可见,只有设计CPU的人需要关心。
  2. 机器语言层(指令集架构层,ISA)

    • 这一层是CPU能够直接执行的指令集,比如MIPS、x86的指令。
    • 每条指令是二进制编码(如 100010...),称为机器码。
    • 汇编语言与机器语言几乎一一对应,只是用助记符(如 ADD R1,R2)代替二进制。
    • 这是硬件和软件之间的"契约":程序员(或编译器)按照这个指令集写程序,CPU就能执行。
  3. 操作系统层

    • 操作系统(如Windows、Linux)对下层(硬件和指令集)进行管理和抽象。
    • 提供系统调用(如读写文件、创建进程),让上层程序不必直接操作硬件。
    • 同时管理内存、进程、设备等。
  4. 汇编语言层

    • 严格来说,汇编语言是机器语言的符号表示,但通常放在操作系统层之上,因为编写汇编程序时可以使用操作系统提供的服务(如中断调用)。
    • 实际上,你可以把汇编语言和机器语言视为同一层的不同表示。
  5. 高级语言层

    • 如C、C++、Java、Python等。
    • 这一层的程序员基本不需要知道底层硬件细节,编译器或解释器负责将高级语言翻译成低层指令。

注意:考研408中常考的"计算机系统层次"主要指:微程序层 -> 机器语言层 -> 操作系统层 -> 汇编语言层 -> 高级语言层,但更常见的是简化成:硬件 -> 指令集 -> 操作系统 -> 应用程序。

层次结构的意义:

  • 每一层可以独立演化(比如换一种CPU,只要指令集兼容,软件不用改)。
  • 降低了软件开发的复杂度。
  • 也是理解"硬件和软件的等价性"的基础:某些功能既可以用硬件实现(快但贵),也可以用软件模拟(慢但灵活)。

层次结构的类比:可以把层次结构想象成"跨国公司的组织结构"——CEO(高级语言层)制定战略决策,不需要知道每个员工(硬件层)具体在工位上做什么。部门经理(操作系统层)负责协调资源,而基层员工(微程序层)执行具体操作。每一层向上级汇报时都做了抽象和概括。

💡 记忆技巧:将"微-机-操-汇-高"记为微机操汇高,谐音"微机操会高"——微型计算机操作会议高级。或者用首字母记忆法:微(微程序)、机(机器语言)、操(操作系统)、汇(汇编)、高(高级)。

跨学科联系(操作系统):层次结构的思想同样贯穿于操作系统中——系统调用接口是操作系统提供给上层软件的服务层,而内核内部又分为进程管理、内存管理、文件系统等多个子系统。理解计算机系统的分层思想,对学习操作系统中的"内核态/用户态"切换、"系统调用过程"等概念非常有帮助。


1.2 计算机的基本组成

冯·诺依曼结构(也称存储程序结构) 现代几乎所有通用计算机都采用这个结构,其核心思想是:将程序(指令序列)和数据存放在同一个存储器中,并且可以按地址访问。

五大部件:

  1. 运算器(ALU,Arithmetic Logic Unit)

    • 负责算术运算(加、减、乘、除)和逻辑运算(与、或、非、异或)。
    • 通常包含一些寄存器(如累加器、状态寄存器),用于暂存操作数和结果。
  2. 控制器(Control Unit)

    • 指挥整个计算机工作。它从存储器中取出指令,翻译指令,然后产生控制信号,告诉运算器、存储器、输入输出设备该做什么。
    • 控制器 + 运算器 = CPU(中央处理器)的核心部分。
  3. 存储器(Memory)

    • 存放程序和数据。冯·诺依曼结构中的存储器是线性编址的,每个地址对应一个存储单元(通常是一个字节)。
    • 分为主存(内存)和辅存(外存,如硬盘)。主存直接与CPU交换数据,辅存用于长期存储。
  4. 输入设备(Input Device)

    • 将外界信息(如键盘按键、鼠标移动)转换成计算机能识别的电信号。
  5. 输出设备(Output Device)

    • 将计算机处理的结果转换成人类能理解的形式(如屏幕显示、打印机打印)。

冯·诺依曼结构的特点:

  • 指令和数据以同等地位存放在同一存储器中(都是二进制形式)。
  • 存储器按地址访问,指令执行顺序一般由程序计数器控制(除非遇到跳转指令)。
  • 指令由操作码和地址码组成。

哈佛结构(了解即可):

  • 指令存储器与数据存储器分开,各自独立编址和访问。
  • 优点是可以同时取指令和取数据(提高效率),常见于嵌入式系统和DSP。
  • 现代CPU内部其实混合了两种结构(如指令Cache和数据Cache分开,但主存还是统一的)。

💡 记忆技巧:冯·诺依曼结构五部件——运控存输输(运算器、控制器、存储器、输入、输出),谐音"运控存叔叔",联想为一个叫"运控"的人去"存叔叔"家。或者用英文首字母:CU+M+ALU+I/O = Controller Unit, Memory, ALU, Input/Output。

冯·诺依曼结构的类比:可以把计算机比作一个"餐厅"——控制器是经理(发号施令),运算器是厨师(加工食材),存储器是冰箱和储物柜(存放食材和菜谱),输入设备是顾客点单,输出设备是上菜。这个类比帮助你理解各部件的协作关系。


1.3 计算机的工作过程

一个程序从编写到执行的过程,你暂时只需理解指令的执行过程。每条指令的执行分为五个基本阶段(经典的五级流水线基础,但这里先讲非流水线的单条指令):

  1. 取指(IF,Instruction Fetch)

    • 控制器根据程序计数器(PC) 中的地址,从存储器中读取一条指令,并存入指令寄存器(IR)。
    • 同时,PC自动增加(指向下一条指令的地址)。
  2. 译码(ID,Instruction Decode)

    • 控制器解析指令寄存器中的指令,确定是做什么操作(如加法、跳转),以及操作数在哪里(寄存器、内存地址等)。
  3. 执行(EX,Execute)

    • 运算器根据控制器的信号,对操作数进行指定的运算(如加法、逻辑与)。
    • 如果是跳转指令,则修改PC的值。
  4. 访存(MEM,Memory Access)

    • 如果指令需要读或写内存(如 LOAD 或 STORE),则在此阶段访问主存。
    • 对于算术逻辑指令,这一步可能不做任何事。
  5. 写回(WB,Write Back)

    • 将运算结果或从内存读出的数据写回寄存器。

几个重要周期概念:

  • 时钟周期:CPU主频的倒数,是CPU内部操作的最小时间单位。比如3GHz CPU,时钟周期约为0.33纳秒。
  • 指令周期:执行一条指令所需的时间,通常包含多个时钟周期。不同指令的指令周期可能不同(比如乘法比加法慢)。
  • 机器周期:通常指从主存读取一个数据字所需的时间,早期CPU常用它作为基准。现代CPU中这个概念已经弱化,但考研中仍可能提及。
  • 总线周期:一次总线传输(如CPU读内存)所占用的时间。

简单例子:假设有一条加法指令 ADD R1, R2(将R1和R2相加,结果存回R1)。

  • 取指:从PC指向的内存取出该指令,PC+1。
  • 译码:发现是ADD,需要读取R1和R2的值。
  • 执行:ALU计算R1+R2。
  • 访存:不需要。
  • 写回:将结果写回R1。

完整示例:LOAD指令的执行 假设有一条指令 LOAD R1, [1000](将内存地址1000处的数据加载到R1),初始PC=200。

  1. 取指:PC=200送MAR,读内存M[200]得到指令编码,送IR,PC增1到204(假设指令长4字节)。
  2. 译码:识别出是LOAD指令,操作数地址1000从指令中提取。
  3. 执行:ALU计算地址(如果是基址寻址,需要加基址;这里是直接寻址,地址=1000),将1000送MAR。
  4. 访存:读M[1000],数据送MDR。
  5. 写回:MDR中的数据写入R1。

💡 记忆技巧:五阶段顺序记为取译执访写——取(指)、译(码)、执(行)、访(存)、写(回)。谐音"取一只仿写"——取来一只(仿写)的指令。注意访存阶段只有LOAD/STORE指令才真正访问内存。

⚠️ 易错点:

  • PC的更新时机:PC是在取指阶段就自动增加的(指向下一条指令),而不是在指令执行完之后。很多初学者误以为PC在写回阶段才更新。
  • 指令周期 vs 时钟周期:一条指令可能包含多个时钟周期,如乘法指令可能需要10个以上时钟周期。不要把指令周期等同于时钟周期。
  • LOAD指令的执行路径最长:LOAD指令经历了完整的五个阶段,且访存阶段需要真正访问内存,因此它是判断CPU性能的关键指令。

1.4 性能指标

这是考试中计算题常考的部分,你需要记住公式并能灵活运用。

  1. 吞吐量(Throughput)

    • 单位时间内完成的任务数量。对于计算机,可以理解为"单位时间内完成的指令数"。
    • 注意:吞吐量受系统中最慢部件限制。
  2. 响应时间(Response Time)

    • 从用户输入到得到输出所经过的时间。对于单个程序,就是它的执行时间。
  3. 主频(Clock Rate)

    • CPU的时钟频率,单位Hz(1Hz = 1次/秒)。常见2.5GHz = 2.5x10^9 Hz。
    • 主频的倒数就是时钟周期。
    • 注意:主频高不一定性能高,因为不同CPU每个周期能做的事不同。
  4. CPI(Cycles Per Instruction)

    • 执行一条指令平均所需的时钟周期数。
    • 例如:某CPU执行程序,总共用了100个时钟周期,共执行了50条指令,则CPI = 100/50 = 2。
    • 不同指令的CPI可能不同(如加法CPI=1,除法CPI=20)。程序总的CPI是平均值。
  5. IPC(Instructions Per Cycle)

    • 每个时钟周期执行的指令数,IPC = 1 / CPI。
  6. CPU执行时间(最重要的公式)

    • CPU执行时间 = 指令总数 x CPI x 时钟周期
    • 或 = 指令总数 x CPI / 主频
    • 例如:一个程序有1000条指令,平均CPI=2,主频2GHz(即2x10^9 Hz),则执行时间 = 1000 x 2 / (2x10^9) = 10^(-6)秒 = 1微秒。
  7. MIPS(Million Instructions Per Second)

    • 每秒执行多少百万条指令。
    • MIPS = 主频 / (CPI x 10^6)
    • 注意:MIPS不能跨不同指令集比较,因为不同指令集完成相同任务需要的指令条数不同。
  8. MFLOPS(Million Floating-point Operations Per Second)

    • 每秒执行多少百万次浮点运算。
    • 常用于科学计算性能评价。
  9. 基准程序(Benchmark)

    • 用一组典型的程序来测试计算机的实际性能,比单纯看主频或MIPS更可靠。
    • 常见基准:SPEC(标准性能评估公司)发布的测试套件。

一个易混淆点:CPU执行时间只包括CPU真正运行程序的时间,不包括等待I/O或操作系统切换进程的时间。而用户感受到的响应时间包括后者。

示例计算1: 某程序编译后共有50000条指令,在某CPU上运行,其中:

  • 加法指令(CPI=1)占40%
  • 乘法指令(CPI=5)占10%
  • 访存指令(CPI=2)占50% 求平均CPI和CPU执行时间(主频1.5GHz)。

解: 平均CPI = 0.4x1 + 0.1x5 + 0.5x2 = 0.4 + 0.5 + 1.0 = 1.9 执行时间 = 50000 x 1.9 / (1.5x10^9) = 95000 / 1.5e9 = 6.33x10^(-5)秒 = 63.3微秒。

示例计算2(进阶): 某程序在CPU A(主频2.0GHz,平均CPI=1.5)上执行,指令数为10^8条。在CPU B上相同程序需要1.2x10^8条指令(因为指令集不同),CPU B的主频为2.4GHz,平均CPI=1.2。问哪个CPU执行这个程序更快?

解(使用CPU执行时间公式): CPU A执行时间 = 10^8 x 1.5 / (2.0x10^9) = 1.5x10^8 / 2.0x10^9 = 0.075秒 CPU B执行时间 = 1.2x10^8 x 1.2 / (2.4x10^9) = 1.44x10^8 / 2.4x10^9 = 0.06秒

结论:虽然CPU B需要执行更多指令,但它的主频更高、CPI更小,总执行时间反而更短(0.06秒 < 0.075秒)。这就是为什么不能仅看主频或MIPS来比较不同架构的CPU。

示例计算3(MIPS计算): 某CPU主频为3.0GHz,平均CPI=2.0,求其MIPS值。

MIPS = 主频 / (CPI x 10^6) = 3.0x10^9 / (2.0 x 10^6) = 1500 MIPS 但注意:这个值只能在同一指令集架构下做比较才有意义。

示例计算4(多类指令平均CPI): 某处理器执行程序,其中算术指令占30%(CPI=1),访存指令占50%(CPI=4),分支指令占20%(CPI=2)。求该程序在处理器上的平均CPI。若主频为2GHz,程序有2x10^6条指令,求执行时间。

解: 平均CPI = 0.3x1 + 0.5x4 + 0.2x2 = 0.3 + 2.0 + 0.4 = 2.7 执行时间 = 2x10^6 x 2.7 / (2x10^9) = 5.4x10^6 / 2x10^9 = 0.0027秒 = 2.7毫秒

⚠️ 易错点:

  • 混淆CPU执行时间和响应时间:响应时间包括I/O等待、进程切换等,CPU执行时间只算CPU真正运算的时间。
  • 用MIPS跨架构比较性能:MIPS在比较x86和ARM时毫无意义,因为一条x86指令完成的功能可能相当于多条ARM指令。
  • CPI是平均值:不同类型的指令CPI不同,不要用一条指令的CPI代替全局平均CPI。
  • 单位换算:1GHz = 10^9 Hz,1MHz = 10^6 Hz。执行时间结果常用微秒(10^-6)或纳秒(10^-9)表示。

性能指标类比:

  • 主频 = 工厂流水线的传送带速度(多快)
  • CPI = 每个产品的组装步数(多少步)
  • 指令数 = 产品总量
  • 执行时间 = 总生产时间

把CPU比喻成工厂:主频快但CPI大(步数多),就像传送带飞快但每个产品需要100个工人操作,不一定比传送带稍慢但每个产品只需10个工人的工厂更快。

💡 记忆技巧:

  • 核心公式:T = I x CPI x T_c(执行时间 = 指令数 x 平均CPI x 时钟周期)
  • 或者 T = I x CPI / f(f是主频)
  • 记忆口诀:"指乘C P乘周期,或指乘C P除主频"
  • MIPS公式记忆:"主频除以C P再除十的六次方"

跨学科联系(操作系统):性能分析在操作系统课程中同样重要——系统吞吐量、响应时间、CPU利用率等都是OS性能评价的核心指标。此外,OS中的进程调度直接影响程序的响应时间(而计算中的CPU执行时间则相对固定)。


📌 408考点提示

考查形式:

  • 选择题常考:层次结构的分层、冯·诺依曼结构特点、指令执行阶段的划分。
  • 计算题必考:CPU执行时间计算、平均CPI计算、MIPS计算。2010-2023年几乎每年都有1-2道相关选择题或综合题。
  • 简答题偶尔出现:冯·诺依曼结构与哈佛结构的区别、层次结构的意义。

常见命题模式:

  1. 给定程序各类指令的占比和各指令的CPI,求平均CPI和CPU执行时间。
  2. 比较两个不同配置的CPU执行同一程序的速度(通过T=IxCPI/f公式)。
  3. 给定主频提升比例和CPI变化,问性能提升多少。

学生常犯错误:

  • 忘记指令总数的单位统一(如K、M、G的换算)。
  • 计算平均CPI时忘记加权平均,直接用算术平均。
  • CPU执行时间公式中混淆CPI和IPC(互倒数关系)。
  • 响应时间和CPU执行时间混用。

备考建议:

  • 熟练背诵并默写CPU执行时间公式的三种形式。
  • 对于性能比较类题目,永远用执行时间公式T=IxCPI/f计算,不要凭直觉判断。
  • 注意408题目中给出的条件单位(MHz还是GHz,ms还是us)。

第一部分小结

概念 核心要点
层次结构 微程序 -> 机器语言 -> 操作系统 -> 汇编 -> 高级语言
冯·诺依曼结构 五大部件:运算器、控制器、存储器、输入、输出;程序和数据同存于存储器
指令执行 取指、译码、执行、访存、写回(五阶段)
性能指标 主频、CPI、CPU执行时间(公式)、MIPS、MFLOPS

进阶练习题(自测)

  1. 某CPU主频为2.5GHz,执行一个程序共需5x10^9个时钟周期,求该程序的CPU执行时间。
  2. 某程序在A机器(主频3GHz,CPI=1.5)上运行需要0.1秒,在B机器(主频2.4GHz)上运行需要0.12秒,问B机器的平均CPI是多少?
  3. 计算机系统层次结构中,哪一层是硬件和软件的"契约"界面?

(答案:1. 2秒;2. CPI=1.44;3. 机器语言层/指令集架构层)