计算机系统概述

原书《操作系统精髓与设计原理——富兰克林》第一章。

基本构成#

  • 处理器:控制计算机的操作,执行数据处理功能
  • 内存:存储程序和数据,又叫内存、主存。
  • 输入输出模块:外部设备。
  • 系统总线:是处理器、内存、输入输出模块间通信的设施。

如上图所示,CPU除了执行操作和数据处理外,还提供了一些寄存器用于存储数据。比如MAR(存储器地址)寄存器用于存储下一次读写的存储器地址,MBR(存储器缓冲)寄存器存储要写入存储器的数据或从中读取的数据。同理,IOAR和IOBR是用来存储IO设备的地址和缓冲。

内存则是一组存储单元,每个单元是一个二进制数,很多这样的单元就组成了一个用于存储数据的空间。其中存储指令或数据。

处理器寄存器#

由于内存的访问相比CPU更加缓慢,所以CPU中通常包含一些寄存器,它们没有内存那么大。

按照作用范围,寄存器可以分成两类:用户可见寄存器控制和状态寄存器

用户可见寄存器#

数据寄存器#

可以被程序员分配给各种函数,比如存储一个数,做累加运算等。

数据寄存器通常是通用的,但也有例外,比如浮点运算可能使用和整数运算不同的寄存器。

地址寄存器#

用于存放数据和指令的内存地址,或者存放用于计算完整地址或有效地址的部分地址。

地址寄存器可以是通用的,也可以是用来以特定方式进行寻址的。

  • 变址存储器:通过给一个基址添加一个索引来获得有效地址
  • 段指针:略,第七章
  • 栈指针:对用户可见的栈进行寻址,该寄存器指向栈顶。

有些处理器会在过程调用(进程切换?)时对所有用户可见寄存器自动保存,在调用返回时恢复;也有的处理器不会自动完成这个功能,程序员需要过程调用前后自行保存用户可见寄存器。

控制和状态寄存器#

在大多数处理器上,这类寄存器对用户不可见,其中一部分可被在内核态执行下的某些机器指令所访问。

先看一下指令执行的周期

程序的指令在内存中,CPU执行一条指令需要先经历取指阶段从内存中取出下一条要执行的指令,然后是执行阶段,执行去到的指令,这一系列操作称为一个指令周期。下面两个寄存器是完成指令周期所不可或缺的:

  • 程序计数器PC:用于保存即将取值的地址
  • 指令寄存器IR:最近取的指令内容

处理器还包括一个或一组寄存器,称为程序状态字(PSW),包含程序的状态信息,如中断的允许或禁止,运行在内核态或用户态。

条件码,用于保存操作结果。

中断寄存器,通常是一组,在使用中断的处理器中用于指向每一个中断处理例程。下面马上会说到中断。

指令的执行#

取指令和执行指令#

PC保存下一次要取的指令地址,处理器从存储器取出一条指令地址,然后递增PC,按顺序取下一条指令。取到的指令被放置在IR中,指令通常分为两部分,一部分是操作位,一部分是数据位。

指令长度为16位,操作码为4位

指令所执行的操作大体上可以分为四种:

  • 处理器-存储器:处理器和存储器之间的数据交换
  • 处理器-IO:处理器和IO设备间的数据交换
  • 数据处理:算数或逻辑操作
  • 控制:这种指令可以改变指令执行顺序。比如PC中的内容是149,IR中的指令是指定下一条指令从地址182处读取,这样PC的值会被设置成182。

假设我们的指令长度是16位,操作码位数是4位,下面是部分控制和数据寄存器还有部分操作码。

下面是一个将内存中的两个数累加并存回内存的例子:

  1. 首先PC寄存器中的地址是300,CPU从存储器的地址300中取指到IR中(这个指令这里用16进制表示,4位16进制就是16位2进制),程序计数器递增
  2. CPU执行IR中的指令,它的操作码是1,数据部分是940,则它会从内存中地址940位置加载数据到AC寄存器中
  3. 从存储器301地址取指令,程序计数器递增
  4. CPU执行指令,5941,操作码是5,数据部分是941,则CPU从内存941处加载数据并和AC中的数据做累加
  5. 最后一个要执行的指令是2941,操作码是2,数据部分是941,CPU将AC中的数据保存到存储器地址941中

IO模块#

CPU也可以直接和IO模块交互,只不过把上面的指令从存储器访问指令换成IO访问指令。

某些情况下IO模块为减轻处理器负担可以直接与存储器交互。这个操作称为直接内存读取(DMA)。

中断#

中断机制主要为了让缓慢的IO操作与处理器操作并发执行。如果没有中断机制,那么每次发起IO操作,处理器必须等待IO操作完成,而IO操作很慢,在这个过程中可能CPU完成几千个不涉及存储器的指令周期。

中断可以被想象成我们高级编程语言中的回调,当发起IO操作后,CPU继续去干自己的工作,而当IO操作完成时,设备发起一个中断,CPU可以接收到这个中断,暂停当前正在执行的程序并去调用中断处理程序来做相应的处理。

除了IO中断,还有一些中断类型:

使用中断后,IO操作分为3部分:

  1. IO操作准备阶段。CPU复制将要输出的数据,准备设备命令参数等(下图中的4)
  2. 实际IO操作,如果不使用中断,程序必须等待IO设备执行操作完成,CPU有可能主动轮询该设备是否操作完成
  3. IO操作完成阶段,用于设置一个表示操作成功或失败的标记。

下图是使用中断和不使用中断的程序控制流:

从用户程序的角度来看,中断也可以被看作当前程序从某处被打断,然后过一会再同一个地方恢复执行。

为了适应中断的存在,指令周期也需要增加相应的阶段:

在执行指令阶段完毕后,若允许中断,则会检查中断,若检查到中断则会挂起当前程序的执行,启动中断处理程序。中断处理程序是操作系统的一部分,它确定中断的性质和要执行的操作。

中断处理#

一下是一个简单的中断处理所包含的事件序列:

  1. 设备给处理器发出一个中断信号
  2. 处理器结束当前指令的执行
  3. 处理器测定并同意该中断,并向中断设备发送确认信息,这个确认信息允许设备取消中断
  4. 因为马上要将控制权移交给中断处理程序,所以处理器需要将当前正在执行的程序的信息保存,比如程序状态字和程序计数器。它们要被压入系统控制栈中。
  5. 由于要执行中断处理程序,所以要把它的入口装入到程序计数器中。
  6. 在第4步时,PSW和PC已经被保存,但还有一些寄存器中的东西需要保存,因为中断处理程序可能会用到这些寄存器,在这一步中把这些数据保存。
  7. 中断处理程序开始处理中断。
  8. 中断处理结束,将被保存的寄存器值恢复到寄存器中
  9. 恢复PSW和PC的值,PC中的值要是来自前面被中断的程序。

多个中断#

在系统正在处理一个中断时可能发生另一个中断。比如在打印机打印结束后,处理它的中断过程中发生了一个通信中断。

最简单的处理办法就是在操作系统正在处理中断时不再理睬任何新的中断请求,新中断会被挂起,当处理器再次允许时,处理器检查是否还有中断发生。

有些中断需要快速被接收,第二种处理方法就是定义中断优先级,允许高优先级的中断打断低优先级的中断处理程序。被打断的中断处理程序的状态也会被保存,稍后被恢复。当一个中断处理程序被恢复之时,一定没有比它更高优先级的尚未恢复的中断处理程序还在挂起。

分级存储架构#

更加快的存储器的单元造价越高,所以计算机中常用分级存储的架构。处于下面图片上层的存储器比它下层的更快,但更小,它其中保存下层的部分数据的副本。

高速缓存#

在指令周期中,处理器至少要访问一次存储器来获得指令,处理器的处理速度往往受到主存读取速度的限制。高速缓存可以保存主存中的部分数据供处理器读取,以缓解处理器和主存之间的速度差异。

访问局部性原理:一个在很多系统中适用的原理,即程序在一段时间内总会访问相同的资源,正是有了这个原理,缓存才能有效的缓解不同设备间的速度差异问题。

高速缓存按块来保存内存中的数据,CPU再按照字节或字来访问这些数据。当处理器想访问主存时,先检查它要访问的字节是否在高速缓存中,如果在就直接使用高速缓存,如果不在,则需要读取内存并以块的形式将读取的数据保存到高速缓存中。

内存由2^n个可寻址的字组成,每个字有唯一的n位地址。高速缓存则是由大小为K个字的块组成,每个块称为一个槽,内存中一共有M=2^n/K个块,高速缓存中的槽位数C显然远远小于内存中的总块数M,不然我们就不需要内存了。

下图是有了高速缓存后CPU读内存的流程图

高速缓存设计#

  • 块大小:稍大的块大小可能会缓存更多有用的数据,导致缓存命中率增加,但如果因为块大小太大,导致高速缓存中的块太少,那么很可能有许多热点数据因为其他数据的进入而被移出高速缓存
  • 映射函数
  • 替换算法:决定当有新块进入高速缓存中时,哪个块被移出。最常用且有效的算法叫LRU(最近最少使用)算法。
  • 写策略:当高速缓存中的内容被修改,何时写回内存。一种策略是块被更新就写回,这可能由于过多的写入导致性能下降;另一种策略是块被替换时写回,这可能会妨碍多处理器操作和IO模块的直接内存读取

I/O通信技术#

可编程I/O#

处理器给IO模块发送命令,IO模块执行这个指令,并设置IO状态寄存器中的位。IO模块在状态改变时并不通知处理器,所以处理器还要定期检查IO模块的状态。

为实现可编程IO,IO软件应该提供三种命令:

  • 控制:告诉外部设备做什么
  • 状态:测试设备状态
  • 传送:在存储器寄存器和外部设备间传送数据

这种技术总让CPU陷入无用的查询繁忙状态中

中断驱动I/O#

上面有,略

直接内存读取#

只是抄书,还不知道它具体的细节 。

虽然中断驱动IO不用等待IO设备执行操作,但在主存和IO设备的数据传输阶段,CPU还是要完全参与,所以,前面两种传送方式都要处理器的干预,它们虽然足以应付通常的任务,但是对于大量数据的移动,如果IO设备能够直接和存储器传送数据就好了。

直接内存读取(DMA)就是用于解决这个问题的办法。

使用DMA时,当处理器需要读写一块数据时,它给DMA模块产生一条命令,发送以下信息:

  • 是否请求一次读写
  • 涉及的IO设备的地址
  • 开始读或写的存储器单元
  • 需要读或写的字数

然后处理器就去做自己的事,DMA模块按字与存储器交互,当传送完成后,DMA模块发送一个中断信号给处理器,因此在开始传送和结束传送时处理器才会参与。

复习题#

自己做一下这些复习题,下面的答案是我自己写的有可能不准确,并非标准答案

1.1 列出并简要的定义计算机的4个主要组成部分#

  1. 处理器:实际执行任务的处理单元,其中也包括一些用于存储和控制的寄存器
  2. 存储器:即内存,用于存储数据以及指令
  3. IO设备:外设
  4. 总线:是以上三个设备的通信设施

1.2 定义处理器寄存器的两种主要类别#

  1. 用户可见寄存器:对用户操作可见的寄存器,主要用于数据存储和计算操作
  2. 控制和状态寄存器:对部分内核操作可见的寄存器

1.3 一般而言,一条机器指令能指定的4种不同的操作是什么#

  1. 处理器-存储器
  2. 处理器-IO
  3. 数据处理
  4. 控制操作

1.4 什么是中断#

IO设备操作完成时用于通知处理器的手段,会中止当前CPU正在执行的任务

1.5 多中断的处理方式是什么#

  1. 当有正在处理的中断时,屏蔽并挂起后来的中断
  2. 第二种办法是基于优先级的中断,优先级高的中断可以打断优先级低的中断,优先级低的中断恢复之前必须执行完所有比它优先级更高的中断

1.6 内存层次的各个元素间的特征是什么#

上一级的比下一级的造价高昂,速度快。

上一级通常作为下一级的缓存,其中保存下一级中部分数据的副本。

1.7 什么是高速缓存#

是用于保存内存种常用的数据块的设备,主要作用是弥补CPU和内存之间的速度差异。

1.8 列出并简要定义I/O操作的三种技术#

  1. 可编程I/O:I/O设备执行操作时,CPU必须不断主动轮询该操作的状态,CPU长时间处于无作用的忙碌状态
  2. 可中断I/O:I/O设备不必再轮询该操作的状态,而是转而去做其他处理,I/O设备处理完成时向CPU发起中断,CPU接收到后,中断处理程序便开始处理之后的事务
  3. 直接内存访问(DMA):在对I/O设备进行读写操作时,CPU不用干预,I/O设备和内存之间进行直接通信

1.9 空间局部性和时间局部性的区别是什么#

这tm讲过吗??

1.10 略#

posted @   yudoge  阅读(328)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~
历史上的今天:
2020-02-21 删除链表的倒数第N个节点
2020-02-21 单词查找树
点击右上角即可分享
微信分享提示
主题色彩