计算机组成原理 个人笔记

前言

快要考计组了,然而才刚刚开始学。虽然看上去很繁杂(确实也挺繁杂),不过似乎可以提炼出几个关键的知识点(来应付考试)。在这里记录下这些关键点和做题方法。

第一章

概要

这一章主要是讲了计算机史和计算机的性能指标

考点

1. 时钟周期

最小的,最基本的时间单位,在一个时钟周期内CPU仅完成一个最基本动作。是时钟频率的倒数。 $$ f=1GHz(10^9Hz),T=1ns $$

2. CPI

执行每条指令的平均时钟周期数

设程序的总指令数为$IC$, 程序执行所需的时钟周期数为$m$,时钟周期为$T$,频率为$f$,那么: $$ CPI = \frac{m}{IC} $$ 如果对于一个程序中的每一指令分别给出它的$CPI_i$和使用频率$P_i$,每类指令的条数$IC_i$,那么$CPI$可以表示为: $$ CPI = \sum_{i=1}^n(CPI_i \times P_i)=\sum_{i=1}^n(CPI_i \times \frac{IC_i}{IC}) $$

3. CPU时间

执行一段程序要花费的时间。某段程序的CPU时间$T_{CPU}$可以表示为 $$ T_{CPU} = CPI \times IC \times T = \frac{CPI \times IC}{f} $$ 常用于衡量优化成功与否,程序运行快慢等。

4. IPC

$$ IPC=\frac{1}{CPI} $$

5. MIPS

每秒百万条指令,可以作为衡量计算机性能的指标。 $$ MIPS = \frac{f}{CPI}=IPC \times f $$

6. MFLOPS

每秒百万次浮点运算。 $$ MFLOPS=\frac{IC_{flops}}{T_{CPU}\times10^6} $$

第二章

概要

这章主要讲了数据在计算机中的表示。

考点

1. 数的机器码表示

由符号和数值一起编码表示的二进制数称为机器数或机器码

原码:数的符号化表示,在开头加上一个符号位。表示直观,但运算复杂,故在计算机中只用于表示浮点数的尾码。

反码:也称1的补码(因为反码和原码相加各位均为1),数值上满足: $$ [x]_\text{反}=\begin{cases} x &{0 \leqslant x \lt 2^n}\ (2^{n+1}-1)+x &{-2^n\lt x\leqslant 0} \end{cases} $$ 即正数的反码等于原码,负数的反码等于原码按位取反(符号位除外)

加法时符号位可以直接参与运算,做减法时将被减数的反码加上减数负数的反码即可。但由于要循环进位,仍没有用于计算机。

补码:也称模2的补码。(因为补码和原码相加为2的次幂,即除最高位其它均为0)

由于模的一些性质,补码的符号位可以直接参与运算,符号位的进位作为模被自动舍弃,减法也可以转换为加法。

补码规则:原码大于0时等于原码,小于等于0时,真值加上模数就是补码。(模数在计算机中常常为字长

eg: 设某计算机字长为8位,求真值 $x=-(10101)2$的补码。 $x{补}=2^8+(-10101)=1110 1011(\mod 2^8)$

计算时有两种快速方法:

  1. 反码法:当$x \lt 0$时,补码等于反码+1。适合用于硬件
  2. 扫描法:当$x\lt 0$时,对真值从右往左扫描,第一个1和右边的0不变,剩下的全部取反。已知补码求原码也一样。

变形补码:也称“模4补码”,由于有两个符号位,除了表示正负还可以表示正溢出负溢出。但因为成本问题依然没有采用。

移码:只用于定点整数表示,编码方式是给真值加上一个常数偏移量。主要应用在浮点数表示上。

2. 浮点数的表示

任何一个二进制数$N$可表示为: $$ N=2^E \times M = 2^{\pm e}\times (\pm 0.m) $$ 类似于十进制科学计数法。

由于$0.01111 \times 2^{101}$还可以表示为$0.1111 \times 2^{100}$,为了统一就需要规格化。常用的标准化有让尾数绝对值大于等于$(0.1)2$即$(0.5){10}$。还有一种参考了十进制科学计数法的是让尾数绝对值在$(1,2)$之间。这样使得最高位始终为1,就可以隐藏。

应用最为广泛的标准就是$IEEE754$。该标准主要包括32位和64位浮点数,分别对应C语言float和double。

单精度浮点数的阶码8位,双精度11位,都有1位符号位,剩下的都用于表示尾数。

$$ N=(-1)^s\times2^{E-127}\times 1.M $$

浮点数和十进制之间互相转化时,都是展开成32位二进制,提取阶码,确定了小数点位置后再处理尾数和符号就可以了。

3.数据校验

两个编码对应二进制位不同的个数称为码距,又称海明距离。码距越大,抗干扰能力、纠错能力越强,但编码效率越低。

根据信息论原理,码距$d$与校验码的检错和纠错能力的关系如下: $$ \begin{cases} d \geqslant e+1 &可检验e个错误\ d \geqslant 2t+1 &可纠正t个错误\ d\geqslant e+t+1 \And e\gt t &可检测e个错误并纠正t个错误 \end{cases} $$

通过在原始数据中引入一部分冗余信息用于校验,利用数据整体的性质去检错甚至矫正错误。

最基本的思想是奇偶校验。通过在最后添加1位作为校验位,要求校验位加上有效信息中的1的数量是偶数,那么接收方通过判断1的数量就可以知道是否出现了奇数位错误。当然,对于偶数位错是无法得知的。

在奇偶校验上发展出了交叉奇偶校验,海明码也是基于此的一种多重奇偶校验。

海明码

由于特别重要,所以单独拆开讲。

通过在2的次幂位置放入校验码,对各自管辖的分区进行多次奇偶校验,即可一步步二分缩小错误的范围。扩展海明码在第一位加入一个校验码对整体进行奇偶校验,从而检验是否两位错。

从本质上来说,多次奇偶校验的每一次,都是在询问校验码对应二进制位置上的那一位是否出错。 如1(0001)询问的是最低位是否出错,2(0010)询问的是倒数第二位是否出错,4(0100)询问第二位。。。这种神奇的性质来源于位置与二进制性质的配合。

多次奇偶校验便于硬件实现,而在计算时,利用二进制性质,可以简单地将所有有效信息为1的位置编码异或,得到的结果就是出错的位置。

一行Python实现海明码:

1
lambda x, y: x ^ y, [i for (i,b) in enumerate(bits) if b]

海明码的校验位只需要$\log_2n$个,通过校验更大的数据量可以让冗余度无限接近0。但这样由于出错率上升,所以要找到一个冗余度与错误率的平衡。更近一步的,由于实际生活中出错很有可能是连续的一块,所以可以采用交织编码方便应用海明码。 海明发明海明码是经过了深思熟虑和多方面的思考。虽然它的原理看上去十分简单,但得到它并不容易。 Luck favors a prepared mind.

CRC循环冗余校验

一种基于模2运算建立编码规则的校验码。

具体来说,给定一个生成多项式,然后根据多项式的系数得到一个二进制除数,在原信息后添加除数长度$r$个0后进行模2除(即每步进行异或),最后得到一个$r-1$位的校验和。把校验和放在原信息的最后,就是带有CRC校验的数据。检验出错时,只需要判断它能否被生成多项式整除即可。

实际上,CRC也能够纠正错误。由于二进制的位独立性,异或满足结合律,所以模2除法满足结合律。那么就可以把出错的那一位通过补0作除法拆分出去。由于CRC编码的非0余数具有循环特性,那么通过对余数循环做除法,就能知道出错的位置。

第三章

概要

第四章

概要

本章介绍了存储系统。

第五章

概要

本章介绍了指令系统。

考点

编址

一条指令有两部分组成:地址码(A,操作数)和操作码(OP) 定长操作码和扩展操作码:四、三、二、一、零地址操作码

寻址

指令寻址:(用指令去控制寻址)

  1. 顺序寻址 PC自动自增执行下一条指令
  2. 跳转寻址 跳转指令 更改PC寄存器

数据寻址:(用数据去控制寻址)

  1. 立即寻址 操作数直接写在指令里,叫做立即数
  2. 直接寻址 指令给出操作数存放的位置
  3. 间接寻址 指令给出存放了有效位置的位置
  4. 寄存器寻址 指令给出存操作数的寄存器
  5. 寄存器间接寻址 指令给出存放操作数地址的寄存器
  6. 隐藏寻址 另一个操作数隐藏在指令中,比如在ACC

偏移寻址:(用寄存器中的值加上指令中的形式地址来寻址)

  1. 基址寻址 用基址BR寄存器或通用寄存器,面向操作系统
  2. 变址寻址 用变址IX寄存器或通用寄存器,面向用户
  3. 相对寻址 对PC加上偏移量

堆栈寻址: (操作数存在堆栈中,用SP寄存器存栈顶地址)

第六章

概要

本章介绍了CPU,指令流水线等。

0%