13015 计算机系统原理 第一章 计算机系统概述

记录学习自考课程编码13015学习过程,献给每一位拥有梦想的"带专人"

第一章 计算机系统概述

冯·诺依曼思想

  • 采用存储程序的工作方式
  • 五大基本部件:主存储器、算数逻辑部件、控制器、通用寄存器、输入/输出部件
  • 部件要能正常工作
  • 指令和数据用二进制表示,指令分为操作码,地址码两部分

冯·诺依曼硬件结构图

计算机系统硬件结构

冯·诺依曼结构主要部件

  1. 用来存放指令和数据的主存储器,简称主存或内存
  2. 用来进行算数逻辑运算的部件 ,即算数逻辑部件 (Arithmetic Logic Unit, ALU),在 ALU操作控制信号 ALUop的控制下,ALU可以对输入端 A 和 B 进行不同的运算,得到结果 F;
  3. 用于自动逐条取出指令并进行编译的部件,即控制元件(Control Unit,CU),也称控制器
  4. 用来和用户交互的输入设备和输出设备

冯·诺依曼结构相关的寄存器

  • 为了临时存放从主存取来的数据或运算的结果,还需要若干通用寄存器 (Gemeral Purpose Gegiter)组成通用寄存器组(GPRs),ALU两个输入端 A 和 B 的数据来自通用寄存器
  • ALU 运算的结果会产生标志信息,例如,结果是否为 0(零标志 ZF)、是否为负数(符号标志 SF)等,这些标志信息需要记录在专门的标志寄存器
  • 从主存取来的指令需要临时保存在指令寄存器(Instruction Register,IR)中
  • CPU 为了自动按序读取主存中的指令,还需要有一个程序计数器 (Program Counter,PC),在执行当前指令的过程中,自动计算出下一条指令的地址并送到 PC 中保存。通常把控制部件、运算部件和各类寄存器互连组成的电路称为中央处理器 (Central Processing Unit, CPU),简称处理器

冯·诺依曼通用寄存器编号

CPU 需要从通用寄存器中取数据到 ALU运算,或把 ALU运算的结果保存到通用寄存器中,因此,需要给每个通用寄存器编号。同样,主存中每个单元也需要编号,称为主存单元地址 ,简称主存地址。通用寄存器和主存都属于存储部件,计算机中的存储部件都从 0 开始编号

冯·诺依曼中的总线

CUP 为了从主存取指令和存取数据,需要通过传输介质和主存相连,通常把连接不同部件进行信息传输的介质称为总线 ,其中,包含了用于传输地址信息数据信息控制信息地址线数据线控制线。CPU 访问主存时,需先将主存地址、读/写命令分别送到总线的地址线、控制线和数据线,然后通过数据线发送或接收数据。CPU 送到地址线的主存地址应先存放在主存地址存储器 (Memory Address register,MAR)中,发送到或从数据线取来的信息存放在主存数据寄存器(MemoryData Register,MDR)中

根据冯·诺依曼思想采用存储程序的工作方式,将需要执行的程序写好,数据准备好,通过输入输出设备放入主存中,CPU 访问主存将地址放入 IR 指令寄存器中,CPU 访问主存将收到的指令放入指令寄存器中,对指令进行译码,获得地址,将地址放入地址寄存器中取完一个指令后程序计数器加一表示下一次访问要访问加一的指令,对译码后的指令放入算数逻辑部件进行运算对需要进行临时保存的变量存入临时寄存器中,对最后运算的结果放回主存然后进行输出。

指令格式

程序是由一系列有序指令组成,用于让计算机执行特定任务或解决特定问题的集合。这些指令是用特定的编程语言编写的。程序通常包括输入处理输出三个部分。通过将这些指令按照逻辑顺序组织起来,程序可以完成从简单的算数运算到复杂的数据处理和用户交互等各种任务。

程序的关键特点

  1. 有序性:所有指令按照特定顺序执行
  2. 确定性:相同的输入在相同条件下会产生相同的输出
  3. 可以移植性:很多程序可以在多个系统上运行,前提是有先赢的编译器或解释器支持

指令是一个单独的命令,指示计算机执行一个特定的操作。指令可以是低级的机器代码,也可以是高级编程语言中的单个语句。在低级编程中,指令通常是二进制格式的,在高级编程语言中,指令则是类似于自然语言的代码行

指令的关键特点

  1. 原子性:每条指令通常代表一个原子的操作或步骤
  2. 执行性:指令是由计算机处理单元直接执行的操作

程序与指令的区别与联系

程序 指令
由多个指令组成 单个命令或操作
高级组织形式 基本单位
用于完成复杂任务 用于执行具体的基本操作
提现整体逻辑和功能 提现具体的运算和操作步骤
例如:一个计算两个数相加的程序 例如:将值从一个寄存器加载到另一个寄存器

冯·诺依曼结构计算机的功能通过执行程序实现,程序的执行过程就是包含的指令的执行过程。

指令 (instruction)是用0和 1 表示的一串0/1序列,用来指示 CPU完成一个特定的原子操作,例如,

  • 取数指令 (load)从主存单元中取出数据存放到通用寄存器
  • 存数指令 (store)将通用寄存器的内容写入主存单元
  • 加法指令 (add)将两个通用寄存器内容相加后送入结果寄存器
  • 传送指令 (mov)将一个通用寄存器的内容送到另一个通用寄存器

定长指令格式

该模型机采用 8 位定长指令字,即每条指令有 8 位,因此指令寄存器 IR 的宽度为 8 位。指令格式有R 型和 M 型两种

op为操作码字段,rs rt为通用寄存器编号,addr为主存单元地址

格式R

  1. 0000 传送 mov
  2. 0001 加 add

格式 M

  1. 1110 取数 load
  2. 1111 存数 store

R[r]表示编号为 r 的通用寄存器中的内容,M[addr]表示地址为 addr 的主存单元内容, <math xmlns="http://www.w3.org/1998/Math/MathML"> ← \leftarrow </math>←表示从右向左传送数据。

指令 1110 0110的功能为 R[0] <math xmlns="http://www.w3.org/1998/Math/MathML"> ← \leftarrow </math>← M[0110] 表示将 6 号主存单元(地址为0110)中的内容取到 0 号寄存器;指令 0001 0001 的功能为 R[0] <math xmlns="http://www.w3.org/1998/Math/MathML"> ← \leftarrow </math>← R[0] + R[1],表示将0 号和 1 号寄存器内容相加的结果送到 0 号寄存器

指令执行过程

存储程序工作方式规定,程序执行前,需将程序包含的指令和数据先送入主存,一旦启动程序执行,则计算机必须能够在无须操作人员干预的情况下自动完成逐条指令取出和执行的任务

如图所示,一个程序的执行就是周而复始执行一条一条指令的过程。每条指令的执行过程:从主存取指令 <math xmlns="http://www.w3.org/1998/Math/MathML"> → \rightarrow </math>→ 对指令进行译码 <math xmlns="http://www.w3.org/1998/Math/MathML"> → \rightarrow </math>→ pc增量(图中的 PC+1表示 PC 的内容加上当前这一条指令的长度) <math xmlns="http://www.w3.org/1998/Math/MathML"> → \rightarrow </math>→ 取操作数并执行 <math xmlns="http://www.w3.org/1998/Math/MathML"> → \rightarrow </math>→ 将结果送至主存或寄存器保存

程序执行前,首先将程序的起始地址存放在 PC 中,取指令时,将 PC 的的内容作为地址访问主存。每条指令执行过程中,都需要计算下条指令将要执行指令的主存地址,并送到 PC 中。若当前指令为顺序型指令,则下条指令地址为 PC 的内容加上当前指令的长度;若当前指令为跳转型指令,则下条指令地址为指令中指定的目标地址。当前指令执行完后,根据 PC 的值到主存中取到的是下条将要执行的指令,因而计算机能够周而复始地自动取出并执行一条一条指令

程序首地址(即指令 I1 所在地址)为 0,因此,程序开始执行时,PC 的内容为 0000.根据程序执行流程,该程序运行过程中,所执行的指令顺序为 I1 <math xmlns="http://www.w3.org/1998/Math/MathML"> → \rightarrow </math>→ I2 <math xmlns="http://www.w3.org/1998/Math/MathML"> → \rightarrow </math>→ I3 <math xmlns="http://www.w3.org/1998/Math/MathML"> → \rightarrow </math>→ I4 <math xmlns="http://www.w3.org/1998/Math/MathML"> → \rightarrow </math>→ I5

实现 z = x + y 功能的每条指令执行过程

指令阶段 I1:1110 0110 I2: 0000 0100 I3: 1110 0101 I4: 0001 0001 I5: 1111 0111
取指令 IR <math xmlns="http://www.w3.org/1998/Math/MathML"> ← \leftarrow </math>← M[0000] IR <math xmlns="http://www.w3.org/1998/Math/MathML"> ← \leftarrow </math>← M[0001] IR <math xmlns="http://www.w3.org/1998/Math/MathML"> ← \leftarrow </math>← M[0010] IR <math xmlns="http://www.w3.org/1998/Math/MathML"> ← \leftarrow </math>← M[0001] IR <math xmlns="http://www.w3.org/1998/Math/MathML"> ← \leftarrow </math>← M[0100]
指令译码 op=1110,取数 op=0000,传送 op=1110,取数 op=0001,加 op=1111,存
PC 增量 PC <math xmlns="http://www.w3.org/1998/Math/MathML"> ← \leftarrow </math>← 0000 + 1 PC <math xmlns="http://www.w3.org/1998/Math/MathML"> ← \leftarrow </math>← 0001 + 1 PC <math xmlns="http://www.w3.org/1998/Math/MathML"> ← \leftarrow </math>← 0010 + 1 PC <math xmlns="http://www.w3.org/1998/Math/MathML"> ← \leftarrow </math>← 0011 + 1 PC <math xmlns="http://www.w3.org/1998/Math/MathML"> ← \leftarrow </math>← 0100 + 1
取数并执行 MDR <math xmlns="http://www.w3.org/1998/Math/MathML"> ← \leftarrow </math>← M[0110] A <math xmlns="http://www.w3.org/1998/Math/MathML"> ← \leftarrow </math>← R[0]、mov MDR <math xmlns="http://www.w3.org/1998/Math/MathML"> ← \leftarrow </math>← M[0101] A <math xmlns="http://www.w3.org/1998/Math/MathML"> ← \leftarrow </math>← R[0]、B <math xmlns="http://www.w3.org/1998/Math/MathML"> ← \leftarrow </math>← R[1]、add MDR <math xmlns="http://www.w3.org/1998/Math/MathML"> ← \leftarrow </math>← R[0]
送结果 R[0] <math xmlns="http://www.w3.org/1998/Math/MathML"> ← \leftarrow </math>← MDR R[1] <math xmlns="http://www.w3.org/1998/Math/MathML"> ← \leftarrow </math>← F R[0] <math xmlns="http://www.w3.org/1998/Math/MathML"> ← \leftarrow </math>← MDR R[0] <math xmlns="http://www.w3.org/1998/Math/MathML"> ← \leftarrow </math>← F M[0111] <math xmlns="http://www.w3.org/1998/Math/MathML"> ← \leftarrow </math>← MDR
执行结果 R[0] = 33 R[1] = 33 R[0] = 16 R[0]= 33 + 16 = 49 M[7] = 49

解读 :指令 I1 存放在第 0 单元,故取指令操作为 IR <math xmlns="http://www.w3.org/1998/Math/MathML"> ← \leftarrow </math>← M[0000],表示将主存 0 单元中的内容取到指令寄存器 IR 中,故取指令阶段结束时,IR 中内容为 1110 0110;然后,将高 4 位 1110(op字段)送到控制部件进行指令译码;同时控制 PC 进行+1操作,PC 中内容变为 0001;因为是取数指令,所以控制器产生主存读控制信号 Read,并控制在取数并执行阶段将 Read 信号送控制线,将指令后 4 位的 0110(addr 字段)作为主存地址送 MAR 并自动送地址线,经过一段时间后,主存将 0110(6#)单元中的 33(变量 y)送到数据线并自动存储在 MDR 中;最后由控制器将 MDR 内容送至 0 号通用寄存器,因此,指令I1 的执行结果为 R[0]=33

其他指令的执行过程类似。程序最后执行的结果为主存 0111(7#)单元内容(变量 z)变为 49,即 M[7]=49

程序的运行

因为计算机无法直接理解和执行高级编程语言程序,因而需要将高级语言程序转换成机器语言程序。这个转换过程通常由计算机自动完成,进行这种转换的软件统称为翻译程序(Translator),被翻译的语言和程序分别称为源语言源程序,翻译生成的语言和程序分别称为目标语言目标程序

翻译程序有以下三类:

  1. 解释程序(Interpreter) :也称解释器。用于将源程序中的语句按其执行顺序逐条翻译成机器指令并立即执行
  2. 编译程序(Compiler) :也称编译器。用于将高级语言源程序翻译成汇编语言或机器语言目标程序
  3. **汇编程序(Assembler):**也称汇编器。用于将汇编语言源程序翻译成机器语言目标程序
阶段 处理程序 处理结果(扩展名)
预处理阶段 预处理器 源程序(.i)
编译阶段 编译器 汇编语音程序(.s)
汇编阶段 汇编器 可重定位目标文件二进制(.o)
链接阶段 链接器 可执行文件二进制
  1. 预处理阶段 :预处理程序(cpp)对源程序中以字符#开头的命令进行处理,例如,将#include命令后面的.h开头文件内容嵌入源程序文件中。预处理程序的输出结果还是一个源程序文件,以.i为扩展名
  2. 编译阶段:编译程序(ccl)对预处理后的源程序进行编译,生成一个汇编语言源程序文件,以.s为扩展名,例如,hello.s 是一个汇编语言程序文件。因为汇编语言与具体的机器结构有关,所以对同一台机器来说,不管什么高级语言,编译转换后的输出结果都是同一种机器语言对应的汇编语言源程序
  3. 汇编阶段 :汇编程序(as)对汇编语言源程序进行汇编,生成一个可重定位目标文件(relocatable object file) ,以.o 为扩展名,例如,hello.o 是一个可重定位目标文件。它是一种二进制文件(binary file),因为其中的代码已经是机器指令,数据以及其他信息也都是用二进制表示的,所以它是不可读的,也即打开显示出来的是乱码
  4. 链接阶段 :链接程序(ld)将多个可重定位目标文件和标准函数库中的可重定位目标文件合并成为一个可执行目标文件(executable object file ),可执行目标文件简称可执行文件。本例中,链接器将hello.o和标准库函数printf()所在的可重定位目标模块printf.o进行合并,生成可执行文件hello.

可执行文件的启动和执行

层次结构

计算机系统层次结构

从应用问题到机器语言程序的每次转换所涉及的概念都是属于软件的范畴,而机器语言程序所运行的计算机硬件和软件之间需要有一个桥梁,这个在软件和硬件之间的界面就是指令集体系结构(Instruction Set Architecture,ISA),简称指令集架构指令系统,它是软件和硬件之间接口的一个完整定义。ISA 定义了一套计算机可以执行的所有指令的集合,每条指令规定了计算机执行什么操作,以及所处理的操作数存放的地址空间以及操作数类型。机器语言程序就是一个 ISA 规定的指令的序列,因此,计算机硬件执行机器语言程序的过程就是让其执行一条一条指令的过程。

实现 ISA 的电路逻辑结构称为计算机组织(Computer Organization)或微体系结构(Mi-croarchitecture),简称微架构。ISA 和微架构是两个不同层面上的概念,例如,是否提供加法指令是 ISA 需要考虑的问题,而加法器采用串行进位还是并行进位方式则属于微架构问题。相同的 ISA 可能具有不同的微架构,例如,对于Inter x86 这种 ISA,很多处理器的组织方式不同,也即具有不同的微架构,但因为它们具有相同的 ISA,因此,一种处理器运行的程序,在另一种微架构的处理器上也能运行。

微架构中的功能由逻辑电路(Logic Circuit)实现,一个功能部件用不同的逻辑实现方式得到的性能和成本有差异,每个基本逻辑电路通过相应的器件技术(Device Technology)实现

计算机系结构的层次划分

虚拟机级别:

  1. 应用语言机器级
  2. 高级语言机器级
  3. 汇编语言机器级
  4. 操作系统 中介

硬件级别:

  1. 机器语言机器级
  2. 微程序机器级

API 与 ABI

  1. API:应用程序编程接口(Application Programming Interface, API)API 定义了较高层次的源程序代码和库之间的接口,通常是与硬件无关的接口
  2. ABI:应用程序二进制接口(Application Binary Interface, ABI)。ABI 是为了运行在特定 ISA 及特定操作系统平台上的应用程序规定的一种机器级目标代码接口,ABI 描述了应用程序和操作系统之间、应用程序和所调用的库之间、不同组成部分(如子程序或函数)之间在较低层次上的机器级代码接口。

性能评价

计算机系统性能评价

  1. 吞吐率(Throughput) :吞吐率表示在单位时间内所完成的工作量,类似的概念是带宽(Bandwidth),它表示单位时间内所传输的信息量
  2. 响应时间(Response Time) :响应时间是指从作业提交开始到作业完成所用的时间,类似的概念是执行时间(Execution Time)等待时间(Latency),它们都是用来表示一个任务所用时间的度量值
  3. 执行时间
    1. 用户 CPU 时间
    2. 系统 CPU 时间
    3. 其他时间(I/O 等待时间)
  4. 流畅度、清晰度、实时性

在对用户 CPU 时间进行计算时需要用到以下几个重要的概念和指标

  • 时钟周期计算机执行一条指令的过程被分为若干步骤,由每一步中相应的操作来完成指令功能。每一步操作都要有相应的控制信号进行控制,用于对控制信号进行定时的同步信号就是 CPU 的时钟信号,其宽度为一个时钟周期,计算机最小时间单位
  • 时钟频率 CPU 的主频就是 CPU 时钟信号的时钟频率,是 CPU 时钟周期的倒数。时钟频率的单位通常为 MHz 或 GHz。主频为 1.0MHz表示每秒钟发生 <math xmlns="http://www.w3.org/1998/Math/MathML"> 1 0 6 10^6 </math>106个时钟信号,因此时钟周期为 <math xmlns="http://www.w3.org/1998/Math/MathML"> 1 0 − 6 10^-6 </math>10−6(秒)= <math xmlns="http://www.w3.org/1998/Math/MathML"> 1 μ 1\mu </math>1μ(微秒);主频未 1.0GHz 表示每秒钟发生 <math xmlns="http://www.w3.org/1998/Math/MathML"> 1 0 9 10^9 </math>109个时钟信号,因此时钟周期为 <math xmlns="http://www.w3.org/1998/Math/MathML"> 10 − 9 s 10-9s </math>10−9s = 1ns(纳秒),表示每秒钟可以执行多少个时钟周期
  • CPI :CPI(Cycles Per Instruction)表示执行一条指令所需的时钟周期数。由于不同指令的功能不同,所需的时钟周期数也不同。对于一条特定指令而言,其 CPI 指执行该指令所需的时钟周期数,此时 CPI 是一个确定的值;对于一个程序或一台机器来说其CPI 指该程序或该机器指令集中的所有指令执行所需的平均时钟周期数,此时 CPI 是一个平均值,通常称为综合 CPI

时钟周期与时钟频率互为倒数关系

已知上述参数或指标,可以通过以公式来计算 用户程序的CPU 执行时间,即用户 CPU 时间

<math xmlns="http://www.w3.org/1998/Math/MathML"> 用户 C P U 时间 = 程序总时钟周期数 ÷ 时钟频率 = 程序总时钟周期数 × 时钟周期 用户 CPU 时间 = 程序总时钟周期数 \div 时钟频率 = 程序总时钟周期数 \times 时钟周期 </math>用户CPU时间=程序总时钟周期数÷时钟频率=程序总时钟周期数×时钟周期

上述公式中,程序总时钟周期数可由程序总指令条数和相应的 CPI 求的

如果已知程序总指令条数和综合 CPI,则可用如下公式计算程序总时钟周期数

<math xmlns="http://www.w3.org/1998/Math/MathML"> 程序总时钟周期数 = 程序总指令条数 × C P I 程序总时钟周期数 = 程序总指令条数 \times CPI </math>程序总时钟周期数=程序总指令条数×CPI

如果已知程序中共有n种不同类型的指令,第 i 种指令的条数和 CPI 分别为 <math xmlns="http://www.w3.org/1998/Math/MathML"> C i C_i </math>Ci 和 <math xmlns="http://www.w3.org/1998/Math/MathML"> C P I i CPI_i </math>CPIi,则

<math xmlns="http://www.w3.org/1998/Math/MathML"> 程序总时钟周期数 = ∑ i = 1 n ( C P I i × C i ) 程序总时钟周期数 = \sum_{i=1}^n (CPI_i \times C_i) </math>程序总时钟周期数=∑i=1n(CPIi×Ci)

程序的综合 CPI 也可以由以下公式求得,其中, <math xmlns="http://www.w3.org/1998/Math/MathML"> F i F_i </math>Fi 表示第 <math xmlns="http://www.w3.org/1998/Math/MathML"> i i </math>i种指令在程序中所占的比例

<math xmlns="http://www.w3.org/1998/Math/MathML"> C P I = ∑ i = 1 n ( C P I i × F i ) = 程序总时钟周期数 ÷ 程序总指令条数 CPI = \sum_{i=1}^n(CPI_i \times F_i) = 程序总时钟周期数 \div 程序总指令条数 </math>CPI=∑i=1n(CPIi×Fi)=程序总时钟周期数÷程序总指令条数

因此,若已知程序综合 CPI 和总指令条数,则可用下列公式计算用户 CPU 时间

<math xmlns="http://www.w3.org/1998/Math/MathML"> 用户 C P U 时间 = C P I × 程序总指令条数 × 时钟周期 用户 CPU 时间 = CPI \times 程序总指令条数 \times 时钟周期 </math>用户CPU时间=CPI×程序总指令条数×时钟周期

有了用户 CPU 时间,就可以评判两台计算机性能的优劣。计算机的性能可以看成是用户 CPU 时间的倒数,因此,两台计算机性能之比就是用户 CPU 时间之比的倒数。若计算机 M1 和 M2 的性能之比为n,则说明"计算机 M1 的速度是计算机 M2 的速度的 n 倍",也就是说,"在计算机 M2 上执程序的时间是在计算机 M1 上执行时间的 n 倍 "

例题1:假设某个频繁使用的程序 p 在机器 M1 上运行需要 10s,M1 的时钟频率未 2Ghz。设计人员想开发一台与 M1 具有相同 ISA 的新机器 M2。采用新技术可使M2 的时钟频率增加,但同时也会使CPI 增加。假定程序 P 在 M2 上的时钟周期数是在 M1 上的 1.5 倍,则 M2 的时钟频率至少达到多少才能使程序 p 在 M2 上的运行时间缩短为 6s?

解:程序 P 在 M1 上执行的时间周期总数为 <math xmlns="http://www.w3.org/1998/Math/MathML"> 用户 C P U 时间 × 时钟频率 = 10 s × 2 G H z = 20 G 用户 CPU 时间 \times 时钟频率 = 10s \times 2GHz = 20G </math>用户CPU时间×时钟频率=10s×2GHz=20G

因为程序 P 在 M2 上的时钟周期数是在 M1 上的 1.5 倍所以 <math xmlns="http://www.w3.org/1998/Math/MathML"> 程序 2 的时钟周期总数 = 20 G ∗ 1.5 = 30 G 程序 2 的时钟周期总数 = 20G * 1.5 = 30G </math>程序2的时钟周期总数=20G∗1.5=30G

要使程序 P 在 M2上运行时间缩短到 6s,则 M2的时钟频率至少应为 <math xmlns="http://www.w3.org/1998/Math/MathML"> 程序总时钟周期数 ÷ 用户 C P U 时间 = 30 G / 6 s = 5 G H z 程序总时钟周期数 \div 用户 CPU 时间 = 30G/6s = 5GHz </math>程序总时钟周期数÷用户CPU时间=30G/6s=5GHz

由此可见,M2 的时钟频率是 M1 的 2.5 倍,但M2 的速度却是 M1 的 1.67 倍 <math xmlns="http://www.w3.org/1998/Math/MathML"> 10 s 6 s = 1.76 10s \ 6s = 1.76 </math>10s 6s=1.76

上述例子说明,由于时钟频率的提高可能会对 CPU 结构带来影响,从而使其他性能指标降低,因此,虽然时钟频率提高会加快 CPU 执行程序的速度,但不能保证执行速度有相同倍数的提高

例题 2:假设计算机 M 的指令集中包含 A、B、C 三类指令,其 CPI 分别为 1、2、4。某个程序 P 在 M 上被编译成两个不同的目标代码序列P1和P2,P1 所含 A、B、C三类指令的条数分别为8、2、2,P2 所含 A、B、C三类指令的条数分别为2、5、3。哪个代码序列总指令条数少?哪个执行速度快?它们的 CPI 分别为多少?

解:P1: <math xmlns="http://www.w3.org/1998/Math/MathML"> 8 + 2 + 2 = 12 条 8 + 2 + 2 = 12条 </math>8+2+2=12条

P2: <math xmlns="http://www.w3.org/1998/Math/MathML"> 2 + 5 + 3 = 10 条 2 + 5 + 3 = 10条 </math>2+5+3=10条

P2 的总指令条数少

P1 的总时钟周期数: <math xmlns="http://www.w3.org/1998/Math/MathML"> 8 × 1 + 2 × 2 + 2 × 4 = 20 8 \times 1 + 2 \times 2 + 2 \times 4 = 20 </math>8×1+2×2+2×4=20

P2的总时钟周期数: <math xmlns="http://www.w3.org/1998/Math/MathML"> 2 × 1 + 5 × 2 + 3 × 4 = 24 2 \times 1 + 5 \times 2 + 3 \times 4 = 24 </math>2×1+5×2+3×4=24

P1执行速度快

CPI 的计算方式为 <math xmlns="http://www.w3.org/1998/Math/MathML"> 程序总时钟周期数 ÷ 程序总指令条数 程序总时钟周期数 \div 程序总指令条数 </math>程序总时钟周期数÷程序总指令条数

P1CPI: <math xmlns="http://www.w3.org/1998/Math/MathML"> 20 ÷ 12 = 1.67 20 \div 12 = 1.67 </math>20÷12=1.67

P2CPI: <math xmlns="http://www.w3.org/1998/Math/MathML"> 24 ÷ 10 = 2.4 24 \div 10 = 2.4 </math>24÷10=2.4

上述例子说明,指令条数少并不代表执行时间短,同样,时钟频率高也不说明执行速度快。在评价计算机性能时,仅考虑单个因素是不全面的,必须三个因素同时考虑

用指令执行速度进行性能评估

指令速度所用的计量单位为 MIPS(Million InstructionsPer Second),其含义是平均每分钟执行多少百万条指令

假定某程序 P 编译后生成的目标代码由 A、B、C、D四类指令组成,它们在程序中所占的比例分别为43%、21%、12%、24%,已知它们的 CPI 分别为1、2、2、2。现重新对程序 P 进行编译优化,生成的新目标代码中 A 类指令条数减少了 50%,其他类的指令条数没有变。请回答下列问题

  1. 编译优化前后程序的 CPI 各是多少
  2. 假定程序在一台主频为 50MHz 的计算机上运行,则优化前后的 MIPS 各是多少

解:

  • A 类指令:比例 43%,CPI 为 1

  • B 类指令:比例 21%,CPI 为 2

  • C类指令:比例 12%,CPI 为 2

  • D 类指令:比例 24%,CPI 为 2

    编译优化前的 CPI 计算公式为:

    <math xmlns="http://www.w3.org/1998/Math/MathML"> C P I = ∑ i = 1 n ( C P I i × F i ) = 程序总时钟周期数 ÷ 程序总指令条数 CPI = \sum_{i=1}^n(CPI_i \times F_i) = 程序总时钟周期数 \div 程序总指令条数 </math>CPI=∑i=1n(CPIi×Fi)=程序总时钟周期数÷程序总指令条数

    CPIbefore <math xmlns="http://www.w3.org/1998/Math/MathML"> = 0.43 × 1 + 0.21 × 2 + 0.12 × 2 + 0.24 × 2 = 0.43 \times 1 + 0.21 \times 2 + 0.12 \times 2 + 0.24 \times 2 </math>=0.43×1+0.21×2+0.12×2+0.24×2

    CPIbefore <math xmlns="http://www.w3.org/1998/Math/MathML"> = 0.43 + 0.42 + 0.24 + 0.48 = 1.57 = 0.43 + 0.42 + 0.24 + 0.48 = 1.57 </math>=0.43+0.42+0.24+0.48=1.57

    编译优化后的 CPI

    编译优化后,A 类指令减少了50%,其他类指令不变

  • A 类指令比例: <math xmlns="http://www.w3.org/1998/Math/MathML"> 43 ÷ 2 = 0.215 43 \div 2 = 0.215 </math>43÷2=0.215

  • B 类指令比例:21%

  • C 类指令比例:12%

  • D 类指令比例:24%

总指令比例现在是: <math xmlns="http://www.w3.org/1998/Math/MathML"> 0.215 + 0.21 + 0.12 + 0.24 = 0.785 0.215 + 0.21 + 0.12 + 0.24 = 0.785 </math>0.215+0.21+0.12+0.24=0.785

编译优化后的比例需要重新归一化(使得总比例为 1),各类指令的新比例为:

  • A 类指令: <math xmlns="http://www.w3.org/1998/Math/MathML"> 0.125 0.785 \frac{0.125}{0.785} </math>0.7850.125
  • B 类指令: <math xmlns="http://www.w3.org/1998/Math/MathML"> 0.21 0.785 \frac{0.21}{0.785} </math>0.7850.21
  • C 类指令: <math xmlns="http://www.w3.org/1998/Math/MathML"> 0.12 0.785 \frac{0.12}{0.785} </math>0.7850.12
  • D 类指令: <math xmlns="http://www.w3.org/1998/Math/MathML"> 0.24 0.785 \frac{0.24}{0.785} </math>0.7850.24

编译优化后的 CPI 计算公式为

CPIafter <math xmlns="http://www.w3.org/1998/Math/MathML"> = 0.125 0.785 × 1 + 0.21 0.785 × 2 + 0.12 0.785 × 2 + 0.24 0.785 × 2 = \frac{0.125}{0.785} \times 1 + \frac{0.21}{0.785} \times 2 + \frac{0.12}{0.785} \times 2 + \frac{0.24}{0.785} \times 2 </math>=0.7850.125×1+0.7850.21×2+0.7850.12×2+0.7850.24×2

CPIafter <math xmlns="http://www.w3.org/1998/Math/MathML"> = 0.274 × 1 + 0.267 × 2 + 0.153 × 2 + 0.306 × 2 = 0.274 \times 1+0.267 \times 2+0.153 \times 2+0.306\times2 </math>=0.274×1+0.267×2+0.153×2+0.306×2

CPIafter <math xmlns="http://www.w3.org/1998/Math/MathML"> = 0.274 + 0.534 + 0.306 + 0.612 = 0.274+0.534+0.306+0.612 </math>=0.274+0.534+0.306+0.612

CPIafter <math xmlns="http://www.w3.org/1998/Math/MathML"> = 1.726 = 1.726 </math>=1.726

MPIS 计算公式 <math xmlns="http://www.w3.org/1998/Math/MathML"> = 主频 C P I = \frac{主频}{CPI} </math>=CPI主频

假定程序在一台主频为 50MHz 的计算机上运行。

编译优化前的MPIS

MPISbefore <math xmlns="http://www.w3.org/1998/Math/MathML"> = 50 1.57 = 31.85 = \frac{50}{1.57} = 31.85 </math>=1.5750=31.85

MPISafter <math xmlns="http://www.w3.org/1998/Math/MathML"> = 50 1.762 = 28.97 = \frac{50}{1.762} = 28.97 </math>=1.76250=28.97

从 MPIS 数来看,优化后程序执行速度反而变慢了

与定点指令运行速度MIPS 相对应的用来表示浮点操作速度的指标是 MFLOPS。它表示每秒所执行的浮点运算有多少百万次,它是基于所完成的操作次数而不是指令数来衡量的。类似的浮点操作速度还有 GFLOPS(10^9^\s)、TFLOPS(10^12^次\s) 、PFLOPS(10^15^次\s)、EFLOPS10^18^次\s

用基准程序进行性能评估

基准程序(benchmarks)是进行计算机性能测评的一种重要工具。基准程序是专门用来进行性能评价的一组程序,能够很好地反应机器在运行实际负载时的性能,可以通过在不同机器上运行相同的基准程序来比较不同机器上的运行时间,从而评测其性能

基准程序最好是用户经常食用的一些实际程序,或是某个应用领域的一些典型的简单程序,对于不同的应用场合,应该选择不同的基准程序。例如,对于用软件开发的计算机进行评测时,最好选择包含编译器和文档处理软件的一组基准程序;而如果是用与 CAD 处理的计算机进行测评时,最好选择一些典型的图形处理小程序作为一组基准程序

练习

  1. 用于存放计算机指令和数据的临时存储器是主存储器

  2. 计算机最基本运算单位是 位/bit

  3. 在计算机系统中,控制器是让计算机按照事先编制好的指令序列来完成各种操作的

  4. 在计算机系统中,运算器负责对信息进行运算处理

  5. 计算机操作原理中指令周期是指一条指令从开始执行到执行完毕的时间

  6. 请简要介绍一下计算机的工作原理

    1. 输入阶段,用户通过输入设备将需要处理的数据输入到计算机中
    2. 存储阶段,计算机将输入的数据暂时存放在主存储器中
    3. 运算阶段,计算机通过运算器对存储器中的数据进行运算处理
    4. 输出阶段,计算机将处理完的数据通过输出设备输出给用户
  7. 写出 z = (x-y)*y 所对应的指令序列

    z=(x-y) * y,x、y 在主存的 5、6号单元,z 存在 7 号单元

    格式 R:0000 (送 mov)、0001(加 add)、0010(减 sub)、0011(乘 mul)

    格式 M:1110(取 load)、1111(存 store)

    主存地址 主存单元内容 内容说明 指令
    0 1110 0110 I1: R[0] \leftarrowM[6]; op = 1110 取数 load r0, 6#
    1 0000 0100 I2:R[1]\leftarrowR[0]; op = 0000 传送 mov r1,r0
    2 1110 0011 I3:R[0]\leftarrowM[5]; op=1110 取数 load r0,5#
    3 0010 0001 I4:R[0]\leftarrow R[0] - R[1]; op-0010 减 sub r0,r1
    4 0011 0001 I5:R[0]\leftarrowR[0] * R[1];op=1100 乘 mul r0,r1
    5 1111 0111 I6:M[7]\leftarrowR[0];op=1111 存数 store 7#,r0
    6 0001 0001 操作数 x = 17
    7 0000 0001 操作数 y = 1
    8 0000 0000 结果为 z,初始值为 0
  8. 名词解释:时钟周期、时钟频率、CPI、吞吐率、响应时间

    1. 时钟周期:计算机执行一条指令被分为若干步,每一步中都有相应的操作来完成指令功能,每一步操作都要有相应的控制信号进行控制,用于对控制信号进行定时的同步信号就是 CPU 的时钟信号,其宽度为一个时钟周期,是计算机最小时间单位
    2. 时钟频率:就是 CPU 的主频,是时钟周期的倒数,单位通常为 MHz 或 GHz,表示每秒钟可以执行多少个时钟周期
    3. CPI:表示一条指令所需的时钟周期数,不同指令功能不同,所需的时钟周期数也不同,对于一条特定指令而言,其 CPI 指的是执行该指令所需的时钟周期数,此时的 CPI 是一个确定的值;对于一个程序或一台机器来说其 CPI 是指该程序或机器指令集中所有指令执行所需的平均时钟周期数,此时CPI 是一个平均值,称为综合 CPI
    4. 吞吐率:单位时间内所完成的工作量,类似的概念是带宽,表示单位时间内所传输的信息量
    5. 响应时间:从作业提交到作业完成所用的时间,类似的概念是执行时间和等待时间,都是用来表示一个任务所用时间的度量值
  9. 假设某机器的时钟频率为4GHz,程序 P 在 M 上的指令条数为 8 \times 10^8,其 CPI 为 1.25,则 P 在 M 上的执行时间是多少?若在 M 上从程序 P 开始启动到执行结束所需时间为 4s,则 P 的用户 CPU 时间所占的百分比是多少

    解:执行时间 = 用户 CPU 时间

    根据公式用户CPU时间 = 时钟周期总数 \div 时钟频率

    时钟周期总数 = 指令条数 \times CPI

    用户 CPU 时间 = (8 \times 10^8 \times 1.25)\div 4 \times 10^9

    = 10 \times 10^8 \div 4 \times 10^9

    =10 \div 40

    =0.25s

    占比 <math xmlns="http://www.w3.org/1998/Math/MathML"> 0.25 4 \frac{0.25}{4} </math>40.25 = 6.25%

捏捏捏捏捏捏捏捏捏捏捏

相关推荐
sre运维13 小时前
运维人员必备的 Mac Zsh 配置技巧
程序员
陈随易1 天前
anime,超强JS动画库和它的盈利模式
前端·后端·程序员
陈随易2 天前
秦少卫-耗时5个月收入超过北京工资的超级独立开发者
前端·后端·程序员
陈随易3 天前
wangEditor,从开源、停更到重生
前端·后端·程序员
黑心萝卜三条杠3 天前
【Go语言】深入理解Go语言:并发、内存管理和垃圾回收
google·程序员·go
一只爱撸猫的程序猿3 天前
在SpringBoot 项目简单实现一个 Jar 包加密,防止反编译
spring boot·安全·程序员
TF男孩3 天前
独立开发上班后:我的故事,你的酒,一腔沉默往前走
程序员
肖哥弹架构3 天前
ScheduledThreadPool线程池设计/场景案例/性能调优/场景适配(架构篇)
java·后端·程序员
陈随易4 天前
兔小巢收费引发的论坛调研Node和Deno有感
前端·后端·程序员
肖哥弹架构4 天前
SingleThreadScheduledExecutor线程池设计/场景案例/性能调优/场景适配(架构篇)
java·后端·程序员