计算机组成原理 Chap.1 计算机系统概述
本系列计算机组成原理博文基于Bilibili王道计算机教育的免费考研课程整理而来, 目的在于系统的梳理计算机专业课的基础知识, 并为将来的面试做好充分的准备.
除本系列外, 计算机考研相关还包括数据结构 / 操作系统 / 计算机网络的相关内容. 会在后续时间内一一进行补足.
引子, 为什么要考计组?
在开始梳理前, 稿主认为有必要明确, 为什么是计组? 计组在整个计算机体系中占据了什么样的地位?
课程中的这张图非常清晰的表述了关于我们会梳理的几门课程的地位. 计组 , 主打的就是一个基础地位, 它描述了计算机的底层硬件架构, 是计算机最基础, 最底层的原理的阐述.
1.1 计算机的发展
我们先明确一个概念, 计算机系统 .
$$ 计算机系统 = 硬件 + 软件 $$
所谓 硬件 , 就是我们所说的看得见, 摸得着的玩意, 主机, 外设之类的玩意.
所谓 软件 , 就是我们所说的操作系统, 程序之类的东西, 它进一步被分为:
- 系统软件: 操作系统, 数据库管理系统, 标准程序库, 语言处理程序, 服务程序(调试Debug…)等.
- 应用软件: 各类对接用户的, 提供更多类型的使用服务的软件.
而一个 计算机系统性能的好坏 , 取决于系统软硬件功能的总和.
显然, 我们计组要探讨的重点不是软件, 我们把话题拉回来, 先谈谈 硬件的发展.
- 电子管 时代
- 第一台 电子数字 计算机: ENIAC(1946) , 使用 电子管 作为逻辑元件
- 这个时代的计算机普遍 体积巨大, 耗电量巨大
趣闻
在这个时代人们普遍使用纸带进行编程, 在纸带上打孔与否来标识0 / 1, 但这时如果有只小虫子死在你的纸带上了, 这个纸带可就毁了.这也是为啥现在找漏洞都叫 Debug 的原因.
晶体管 时代
- 以 晶体管 作为逻辑元件, 相比于电子管, 体积要小得多
- 开始出现 面向过程的程序设计语言 (FORTRAN), 开始出现 操作系统
中小规模集成电路 时代
- 逻辑元件越来越小, 人们开始将其集中集成在一个基片上
- 可靠性高得多
- 各种 高级语言 开始出现, 出现 分时操作系统
大规模 / 超大规模集成电路 时代
- 开始出现 微处理器(CPU) / 微型计算机
- 个人计算机(PC)开始萌芽
概念: 制造工艺
即每个晶体管在集成电路中所占宽度不超过的值. 常见的13nm, 7nm, 5nm, 3nm等都属于这个范畴.
概念: 逻辑元件
指的是计算机用来处理电信号(用于表示0 / 1的低电平 / 高电平)的最小的基本单元.
我们谈到了 微处理器(CPU) , 那么自然, 我们把这玩意但拉出来聊聊.
Intel(英特尔, 牙膏厂 ) 是此前时代中最富盛名的CPU供应商. 我们拿它推出的芯片来举例.
- 8080
- 机器字长: 8位
- 8086
- 机器字长: 16位
- Pentium(奔腾)
- 机器字长: 64位
概念: 机器字长
计算机一次整数运算能够处理的二进制位数. 自从进入奔腾处理器后, 包括后续的酷睿系列, 都保持了机器字长64位的形式.
趣闻
除了 Intel , 还有一家供应商叫 AMD , 而这两家企业的创始人来自于同一个公司 仙童半导体公司 , 集成电路这个概念也是由这家公司捅咕出来的.
摩尔定律
由Intel公司创始人之一 摩尔( Gordon Moore ) 提出的经验之谈, 每隔18个月, 集成电路上可容纳的晶体管数量会增加1倍 .
注意: 摩尔定律的适用范围
值得注意的是, 由于制造工艺的瓶颈, 该定律已经逐步失效. 但我们不应当忽视该定律造成的影响.
1.2 计算机系统的组成
1.2.1 计算机硬件的基本组成
谈及 计算机硬件 , 就离不开一个人: 冯·诺依曼(John von Neumann) .
我们要谈到的硬件结构大致可分为以下两种:
- 冯诺依曼机
- 现代计算机
我们上一节提到了ENIAC, 世界上第一台计算机, 事实上, 冯 诺伊曼正是这台计算机的 设计顾问 .
冯 诺伊曼首先提出的问题是关于计算机执行程序方式的. ENIAC上, 计算机执行程序是需要依赖 手动接线 的, 即程序员需要根据下一步要运行的计算来手动调整计算机的线路.
冯老寻思一下这不行啊, 就提出了这么个概念: 存储程序 .
概念: 存储程序
存储程序 , 指将指令以 二进制代码 的形式事先输入计算机的 主存储器 , 随后按照存储地址顺序来依次执行全部指令, 直到程序执行结束.
我们解释一下这图啥意思:
- 输入设备 : 将信息转换为计算机能够识别的形式(就二进制嘛)输入
- 运算器 : 进行算术运算 / 逻辑运算
- 存储器 : 存放数据和程序
- 控制器 : 利用电信号协调工作, 解析存储器中的指令
- 输出设备 : 将计算后的信息转换为可读形式输出
注意: 上图中箭头的区别
上图中, 实线箭头 表示数据线, 虚线箭头 表示控制线 / 反馈线.
总结一下冯诺依曼机的几个特点:
- 由 5大部件 组成
- 指令和数据 以同等地位存储在存储器中
- 指令和数据用 二进制 表示
- 指令由 操作码 和 地址码 构成
- 运用了 存储程序 的设计思想
- 以 运算器 为中心( 任何数据的传送一定会通过运算器完成 )
问题这就出来了, 运算器 这玩意本来是负责算数的, 数据传送这种活不应该派给它是不.
后面人寻思寻思, 把冯诺依曼机改吧改吧, 衍生出了 现代计算机的结构 .
现代计算机的结构特点有以下几点:
- 以存储器为中心 (这回运算器不用干数据传送这累活了)
- 由于 运算器 与 控制器 的紧密相关, 因此现代设计工艺中, 通常运算器与控制器在同一个芯片上, 我们称之为 CPU
注意: 主机的概念
概念: 主机
在计组中, 主机 指的是CPU(运算器+控制器)与 主存储器 的合称. 我们所说的 内存 即属于主存之类. 而我们通常说的 磁盘, 固态 , 属于 辅助存储器(辅存) , 它应当被归类于 I/O设备 , 并不在主机之列.
1.2.2 计算机各硬件的工作原理
看完了组成, 我们自然要来看看原理. 既然现代计算机以存储器为中心, 我们不妨从主存开始.
1.2.2.1 主存储器
主存储器由以下三个主要部分:
- 存储体
- MAR
- MDR
概念: MAR(Memory Access register, 地址寄存器)
存放和地址相关的二进制数据.
概念: MDR(Memory Data register, 数据寄存器)
存放和数据相关的二进制数据
CPU 读出数据 的过程如下:
- CPU将数据所在地址写入MAR
- 主存储器根据MAR中的地址在存储体中找到数据, 将该数据写入MDR
- CPU从MDR中读出该数据
CPU 写入数据 的过程与之类似:
- CPU将要写入的数据写入MDR, 将要写入的位置写入MAR
- 通过控制总线向主存发出写指令
- 主存将MDR中的数据存入MAR指向的地址中
好, 我们转回头来, 看主存储器中最主要的部分: 存储体 .
数据在存储体内是要按 地址 来进行存储的, 这样的好处不言自明, 写入 / 读出数据时, 能够很清晰的通过地址得到具体数据.
地址 在存储体中的具体体现即 存储单元 . 一个存储单元能够存储一串二进制代码.
概念: 存储字(word)
1个存储单元中存放的数据被称为1个存储字.
概念: 存储字长
一个存储字的位数. 在现代计算机系统中, 通常是 8bit(8比特) 的整数倍.
有了这些概念, 编址就很容易理解了. 每个存储字对应一个地址 , 从0开始. CPU将地址号写入MAR, 读出 / 写入对应的字即可.
有了如上关系, 我们来深究一下一个很重要的公式:
显然, MAR这个寄存器的位数与存储单元的个数直接挂钩. MDR的位数应当与计算机的存储字长相等.
我们好像能通过MAR和MDR的位数来算出其主存储器中存储体的大小!
例子
4位MAR, 16位MDR.
意味着该存储体有 $ 2^4 $ 个存储单元, 单个存储单元的长度为 $ 16 $ .
存储体大小: $ 2^4 \ast 16 = 2^8 = 256bit $
注意: 字与字节
一个字(word) 有多少位是根据计算机本身的结构而决定的, 而 一个字节(Byte) 的长度固定, 是8bit.
1.2.2.2 运算器
运算器最主要的部件如下:
- ACC(Accumulator, 累加器) : 用于存放操作数或运算结果
- MQ(Multiple-Quotient Register, 乘商寄存器) : 在乘除运算时, 用于存放操作数或运算结果
- X(通用寄存器) : 用于存放操作数
- ALU(Arithmetic and Logic Unit, 算术逻辑单元) : 通过内部逻辑电路来实现算数运算和逻辑运算
1.2.2.3 控制器
控制器中的主要部件如下:
- CU(Control Unit, 控制单元) : 分析指令, 给出控制信号
- IR(Instruction Register, 指令寄存器) : 存放当前要执行的指令
- PC(Program Counter, 程序计数器) : 存放下一条指令的地址, 实际执行中可以自动+1
设计这三个部件的原因, 与当前时代中控制单元执行指令的流程有关:
- 取指令(PC的活)
- 分析指令(IR要把指令暂存进来)
- 执行指令(CU的活)
注意: 指令周期
计算机的指令执行远不止这么简单, 这里权为读者留个大致印象, 后续的篇章中会有专门的指令周期说明.
我们这里把这张图放在这里当作总结, 希望读者能够再次回顾前面的知识.
注意: MAR / MDR的位置
由于MAR与MDR与CPU交互的情况过于频繁, 当前制造工艺中常常将这两个本应属于主存的寄存器集成在CPU上, 在此作为补充知识进行说明.
1.2.3 计算机软件
其实这部分不应该塞到计组里面来说的, 但是为了我们知识的系统性, 还是大致提一嘴.
我们上面提过关于 软件的分类 , 即 系统软件 以及 应用软件 . 这里就不再详述了.
注意: 软件的分类
该部分内容请见1.1
我们现在需要更进一步, 了解一下这些软件是怎么编出来, 又是怎么被运行的.
当前的计算机语言由高至低可分为:
- 高级语言 : C/C++, Java, Python
- 汇编语言 : 主要表现为助记符的形式
- 机器语言 : 即计算机能够直接执行的二进制代码
通常的软件编写过程, 需要用户利用高级语言编写源程序, 随后经过 编译程序(编译器) 转译为汇编语言, 最后经过 汇编程序(汇编器) 翻译为机器语言.
注意: 语言的翻译过程
上述过程是典型的高级语言运行流程, 如C/C++; 但随着不同高级语言的发展, 有些高级语言语言能够跳过第一步, 直接通过编译程序将高级语言翻译为机器语言; 还有些高级语言(JavaScript, Python, Shell, 我们也称之为 脚本语言 )是通过 解释程序(解释器) 边执行边解释代码来运行的.举例而言, 我们通过C/C++写的程序可以直接编译为一个exe文件, 随后这个文件可以直接单独运行而无需任何环境. 但通过脚本语言写的程序则在每一次运行时都需要重新将代码翻译一遍.
我们聊这些, 主要是为了让读者明白, 软件和硬件在逻辑功能上是等价的 . 通常而言, 硬件的 性能高 / 成本高 ; 软件的 性能低 / 成本低 .
例子
同样实现 乘法 这一效果, 我们可以使用硬件单独提供的乘法电路 , 异或直接通过循环相加这种软件的方式. 二者所达成的效果是相同的, 但是在运行效率和设计成本上有显著的差异.
概念: 指令集体系结构(ISA)
指令集体系结构 , 英文名称 Instruction Set Architecture , 是软件与硬件之间的接口, 它定义了一台计算机的硬件实现了哪些指令, 以及每条指令应当如何使用.
1.2.4 计算机系统的层次结构
本节中的层次结构与上一小节中的计算机语言几乎可以说是层层对应. 我们仍然按照从高到低的结构来聊:
- 虚拟机器 M4(高级语言机器)
- 虚拟机器 M3(汇编语言机器)
- 虚拟机器 M2(操作系统机器)
- 传统机器 M1(机器语言机器)
- 微程序机器 M0(微指令系统)
我们能看到有3个层级与我们上面的语言划分完全一一对应, 但多出来这俩玩意 操作系统机器 和 微程序机器 是个什么玩意?
操作系统机器泛泛而言可以解释为是系统提供给上层的 系统调用(System Call) , 相当于操作系统在机器语言上单独翻译了一层, 上层无需考虑复杂的机器码, 只需要调用操作系统提供的功能即可.
概念: 微指令
实际上, 就是将原先一条条的机器指令再度拆分为一条条功能更加细化, 在系统内设定好的指令, 我们称之为 微指令 .
例子
举例而言, 我们要将 变量y加1 , 我们应该首先将 变量y放入运算器的某个寄存器中 , 随后 运算器进行运算, 将结果储存在某个寄存器中 , 再将这个结果存回原先y的地址 . 着一条条更为细分的指令就是微指令.
我们需要明确, 从 M2~M4 是我们所说 软件 的部分, 而 硬件 部分则是下层的 M0~M1 .
显然, 我们在计组中, 要重点关注下面这两层.
1.3 计算机性能指标
我们聊完了硬件的组成部分, 自然要聊聊该怎么判断这玩意好不好.
1.3.1 存储器的性能指标
谈到存储器, 有个我们避不开的指标: 容量 . 自然, 越大越好.
注意: 存储器容量的计算
见1.2.2.1中的内容.
1.3.2 CPU的性能指标
CPU中比较重要的指标是 主频 . 谈及这个, 我们还得说一下 CPU的时钟周期 这个概念.
概念: CPU的主频
指的是CPU内部数字脉冲信号震荡的频率.
概念: CPU的时钟周期
指的是CPU内完成一次信号震荡所用的时间.
$$ CPU主频 = \frac{1}{CPU时钟周期} $$
我们之前所说的 微指令 是要严格遵循CPU的时钟周期的, 即一条微指令必须在一个 / 或几个CPU的时钟周期内完成. 因此 CPU主频越高, 通常也意味着CPU越快 .
注意: CPU速度的影响因素
概念: CPI
凡事无绝对, CPU的速度也受到 CPI(Clock cycle Per Instruction) 即执行一条指令所需的时钟周期数. 显然, 这个周期数越小越好, 通常是个平均值.
我们得到CPI, 可以得到 执行一条指令的平均耗时 .
$$ 执行一条指令的平均耗时 = CPI \ast CPU时钟周期 $$
除了上面提到的指标, 还有些花里胡哨的玩意, 在这都列举一下:
概念: IPS
IPS(Instruction Per Second) , 即每秒执行多少条指令, 同样通常是个平均值.
$$ IPS = \frac{主频}{平均CPI} $$
概念: FLOPS
FLOPS(Floting-point Operations Per Second) , 即每秒执行多少次浮点运算.
1.3.3 系统整体性能指标
不整什么花里胡哨的了, 直接写了.
概念: 数据通路带宽
数据总线一次能够并行传送信息的位数.
概念: 吞吐量
系统在单位时间内处理请求的数量.
概念: 响应时间
用户向计算机发送请求到系统对该请求做出相应并获得所需结果的等待时间.
本章主要是对计算机的系统进行了一定概述. 主要目标在于让读者大致明确 / 了解 计组在搞些什么玩意. 能学到些什么知识 .
本篇博文就到这里~