最近发现很多小伙伴工作很久了,大部分工作都是在重复的进行CRUD,对于一些基础性的知识,比如:计算机基础知识,操作系统,数据结构和算法等,却了解的少之又少。
其实,很多时候,这些基础性的知识往往是造成程序员职业生涯瓶颈的一个重要的因素。所以,冰河强烈建议这些基础知识越早知道越好,越早掌握越好!最好是在大学时期就充分掌握这些计算机基础知识。
好了,接下来,冰河为大家总结了一篇万字长文系统介绍计算机中有关数据方面的基础知识。
数据的表示形式
在计算机中,所有的数据都是以二进制的形式进行表示的,也就是说,在计算机中使用0和1来表示所有的数据。而我们日常生活中的数字都是10进制的,那我们平时使用的数字如果在计算机中表示时就需要进行进制的转换。
进制转换
R进制转10进制
R进制转10进制可以使用按权展开的方法,具体的操作就是:将R进制数的每一位数值使用R^k^表示,底数是R,指数是k。
其中,k与该位和小数点之间的位置有关。当这个位置位于小数据左边时,k的值是从小数点向左依次数的个数,需要注意的是:紧邻小数点的数字位置为0,接下来是1,2...依次类推。同样的,如果这个位置在小数点的右边,则紧邻小数据点位置的数字从-1开始,依次向右数为-2,-3等等,依此类推。
例如,我们给出一个二进制数字,11010101.01,转换为10进制数字为:1 x 2^7^ + 1 x 2^6^ + 0 x 2^5^ + 1 x 2^4^ + 0 x 2^3^ + 1 x 2^2^ + 0 x 2^1^ + 1 x 2^0^ + 0 x 2^-1^ + 1 x 2^-2^。
图片
再比如,我们给出一个八进制数,76128.01,转换为10进制数字为:7 x 8^4^ +6 x 8^3^ + 1 x 8^2^ + 2 x 8^1^ + 8 x 8^0^ + 0 x 8^-1^ + 1 x 8^-2^
图片
十进制转R进制
十进制转R进制就比较简单了,这里我们可以使用短除法。
例如,将十进制数字69转换为二进制的过程如下所示。
图片
得出短除的结果后,我们需要将余数倒过来排列即为十进制69转换为二进制的结果,所以结果数据为:1000101。
二进制与八进制互转
二进制转八进制时,每三位二进制数表示一个八进制数。因为在八进制中,总共有8个基数,分别是0~7,逢8进1。而如果要使用二进制来表示时,0的二进制为000,7的二进制为111,所以,每三位二进制数对应一位八进制数。反过来,每一位八进制数对应三位二进制数。
具体的划分策略是,从二进制的低位开始,从低到高,也就是从右向左,每三位二进制数对应一个八进制数,不足三位的前面补0,例如,我们将二进制数:10001110转化为八进制数的过程,具体如下所示。
图片
所以,二进制数10001110转化为八进制数的结果为216。
同理,八进制转二进制与二进制转八进制正好相反,八进制的每一位对应三位的二进制数。也就是说,将八进制数的每一位转化成三位的二进制数即可。
二进制与十六进制互转
在十六进制表示的数字中,总共有15个基数,为0~15,逢16进1。如果要将二进制数转化为十六进制数时,首先要弄清楚每位十六进制数需要多少为二进制数表示。
在十六进制中,最大的基数为15,15的二进制表示为:1111,最小的基数为0,0的二进制数为0000,也就是说,十六进制的基础使用二进制表示为 0000~1111,所以,每位十六进制数需要四位二进制数表示。
从二进制数的低位开始,也就是从右侧开始,每四位二进制数对应一位十六进制数。
例如,我们需要将二进制数10001110转换为十六进制数,如下所示。
图片
注意:在十六进制中,分别使用A,B,C,D,E,F代表10,11,12,13,14,15。
所以,二进制10001110转化为十六进制的结果为8E。
十六进制转二进制与二进制转十六进制正好相反,将十六进制的每一位转换为四位二进制数即可。
数据的码制
在计算机中,带符号的机器数可以采用原码、反码、补码和移码表示,这些编码称为码制。
原码
在原码表示中,最高位是符号位,0表示正号,1表示负号,其余的n-1位表示数值的绝对值,数值0的原码有两种表示形式:原 = 0 0000000,原 = 1 0000000。
反码
在反码中,最高位是符号位,0表示正号,1表示负号,正数的反码与原码相同,负数的反码是其绝对值按位取反。数值0的反码有两种表示形式:反 = 0 0000000,反 = 1 1111111。
补码
在补码中,最高位是符号位,0表示正号,1表示负号,正数的补码与原码和反码相同,负数的补码等于其反码的末位加1。在补码的表示中,0有唯一的补码:补 = 0 0000000,补 = 0 0000000。
移码
移码表示法是在数X上增加一个偏移量来定义的,常用于表示浮点数中的阶码。如果机器字长为n,规定偏移量为 2^n-1^。
实际上,在偏移 2^n-1^的情况下,只要将补码的符号位取反就可以获得相应的移码。
码制总结
我们来看下面的表格,这里,我直接使用八位的二进制数来表示相应的数值。
码制 | 数值1 | 数值-1 | 1-1 |
原码 | 0000 0001 | 1000 0001 | 1000 0010 |
反码 | 0000 0001 | 1111 1110 | 1111 1111 |
补码 | 0000 0001 | 1111 1111 | 0000 0000 |
移码 | 1000 0001 | 0111 1111 | 1000 0000 |
通过表格我们发现:
- 正数的原码、反码和补码是相同的。
- 负数的反码是原码除符号位外,其他位分别取反;
- 负数的补码是其反码的末位加1。
- 移码是在补码的基础上符号位取反得到。
在负数的原码和补码的转换中,我们可以得出如下结论:
- 负数的原码转补码是在原码的基础上除符号位外,其他位取反,然后末位加1。
- 负数的补码转原码是在补码的基础上除符号位外,其他位取反,然后末位加1。
也就是说,负数的原码转补码和补码转原码的规则是一样的。小伙伴们可以根据表格自行验证
计算机使用补码进行加减法运算
我们再来看表格的最后一列 1-1,在计算机中,表示为1+(-1),其正确的结果应该为0。接下来,我们分别分析下使用原码、反码、补码和移码进行加减法运算的结果的正确性。
- 表格的第一行中,使用原码计算的结果为1000 0010,转换为10进制数为-2,1-1不等于-2,所以,使用原码进行加减法运算的结果是错误的。
- 在反码中,计算1-1的结果为1111 1111,显然结果不为0,所以,使用反码进行加减法运算的结果是错误的。
- 在补码中,计算1-1的结果为0000 0000,结果为0,所以,使用补码进行加减法运算的结果是正确的。
- 在移码中,计算1-1的结果为1000 0000,结果为-0,虽然-0也等于0,但是严格意义来讲,这个结果是不正确的。
在计算机中,不会使用移码进行加减法运算,移码用于浮点数的阶码。
数值的表示范围
在计算机中,码制所表示的范围,可以分为定点整数和定点小数。在定点数中,小数点是固定的。定点整数就是说小数点在最低位的后面,也就是在最右面,此时的小数点可以忽略不写。定点小数就是小数点在最高位的前面,也就是在最左边。
值得注意的是:在定点整数和定点小数中,小数点都不占位数。所以,小数点在定点整数和定点小数中不会影响数值的范围。
我们可以将定点整数和定点小数的取值范围总结成下表所示。
码制 | 定点整数 | 定点小数 |
原码 | -(2^n-1^ -1) ~ +(2^n-1^ -1) | -(1-2^-(n-1)^) ~ +(1-2^-(n-1)^) |
反码 | -(2^n-1^ -1) ~ +(2^n-1^ -1) | -(1-2^-(n-1)^) ~ +(1-2^-(n-1)^) |
补码 | -2^n-1^ ~ +(2^n-1^ -1) | -1~ +(1-2^-(n-1)^) |
移码 | -2^n-1^ ~ +(2^n-1^ -1) | -1~ +(1-2^-(n-1)^) |
表格中的n表示机器的字长,也就是用多少位二进制数表示。
这张表小伙伴们不用死记硬背,说白了,这张表,冰河也记不住,那我们怎么办呢?不慌,这里,我给大家举一个例子。
例如,我们这里使用4位机器字长来表示,为了理解方便,这里我用四个方框来表示4位二进制数。
图片
默认最高位为符号位,如下所示。
图片
这里我们先用4位二进制数表示定点整数,则最小值为1111,最大值为0111。
最小值1111表示如下。
图片
其转换成10进制数为-7。
最大值0111表示如下。
图片
其转换为10进制数为7。
这样,我们使用4位二进制数表示的范围,则可以计算出结果为:-7 ~ 7。也就是 -(2^4-1^ - 1) ~ +(2^4-1^ -1),所以,当使用n位二进制数表示数值的范围时,我们可以得出数据的表示范围为:-(2^n-1^ - 1) ~ +(2^n-1^ -1)
所以,我们根本就不需要记住定点整数和定点小数的取值范围表,只需要简单的使用一个实际的二进制位进行验算即可得出正确的结果数据。比如,我这里以4位二进制位进行验算举例。
还有一点需要注意的是:补码和移码比原码和反码少一个数,就是-0。另外,验证定点小数和验证定点整数的方式相同,小伙伴们可自行验证定点小数的值,这里,我就不再赘述。
如果我们使用8位二进制数表示,则定点整数的取值范围为:
1111 1111 ~ 0111 1111 转换为十进制数就是:-127 ~ 127,将二进制数转换为补码为:1000 0000 ~ 0111 1111。
其中,-128的补码为1000 0000是人为规定的。
如果使用8位二进制数表示,则定点小数的取值范围为:
-0.1111 1111 ~ +0.11111111,补码的范围为:-1~ + +0.11111111。
其中,-1的补码为1000 0000是人为规定的。
浮点数的运算
浮点数的表示
首先,我们先来看下浮点数的表示形式,浮点数的表示形式如下,
N = 尾数 * 基数^指数^
对于浮点数来说,我们最常说的就是圆周率 π,数学上常使用3.14来表示π的值,如果使用科学计算法的话,我们可以使用形如3.14 * 10^3^ 这样的数来表示。其中,在3.14 * 10^3^中,3.14表示尾数,10表示基数,3表示指数。
另外,3.14 * 10^3^ 可以写成多种形式,比如可以写成 0.314 * 10^4^,也可以写成0.0314 * 10^5^。
浮点数的存储格式
浮点数在计算机中的表示中,阶码是带符号的纯整数,尾数为带符号的纯小数。浮点数的表示格式如下所示。
一个数的浮点数表示不是唯一的。当小数点的位置发生改变时,阶码也会相应的改变。可以使用多个浮点形式表示同一个浮点数。浮点数的数值范围主要由阶码决定,数值的精度则是由尾数决定的。
浮点数的运算过程
运算的过程要依次经历对阶、尾数计算和结果格式化三个阶段。
例如计算:3.14 * 10^3^ + 1.5 * 10^5^的结果数据。
首先,我们需要先进行对阶操作,这里有个原则就是小数向大树看齐,这里我们需要将3.14 * 10^3^进行对阶操作,转化成0.0314 * 10^5^,然后与1.5 * 10^5^进行相加操作,得出结果数据1.5314 * 10^5^。
接下来,我们再来看看浮点数的特点。
浮点数的特点
浮点数的主要特点如下所示。
- 一般尾数使用补码表示,阶码使用移码表示。
- 阶码的位数决定数的表示范围,位数越多范围越大。
- 尾数的位数决定数的有效精度,位数越多精度越高。
- 对阶时,小数向大数看齐。
- 对阶是通过较小数的尾数右移实现的。
计算机结构
计算机结构主要由运算器、控制器、存储器、输入设备和输出设备组成。简化的结构图如下图所示。
图片
接下来,我们再看看看其详细的结构图如下所示。
图片
其中,主存储器又叫做内存储器,也就是内存;辅助存储器又叫做辅存,也就是外存储器,例如磁盘;CPU的核心部件为运算器和控制器。
CPU由运算器、控制器、寄存器组和内部总线组成。
运算器包含:算术逻辑单元、累加寄存器、数据缓冲寄存器、状态条件寄存器。
- 算术逻辑单元(ALU):数据的算术运算和逻辑运算。
- 累加寄存器(AC):通用寄存器,为ALU提供一个工作区,用于暂存数据。
- 数据缓冲寄存器(DR):写内存时,暂存指令或数据。
- 状态条件寄存器(PSW):存储状态标志和控制标志,有时也可以将状态条件寄存器归为控制器部分。
控制器包含:程序计数器、指令寄存器、指令译码器、时序部件。
图片
- 程序计数器(PC):存储下一条要执行的指令的地址。
- 指令寄存器(IR):存储即将执行的指令。
- 指令译码器(ID):对指令中的操作码字段进行分析解释。
- 时序部件:提供时序控制信号。
计算机体系结构分类
首先,我们先来看一个在计算机领域中,对计算机的体系结构进行分类的一种经典方法,就是Flynn分类法,Flynn分类法将计算机分成单指令流单数据流、单指令流多数据流、多指令流单数据流、多指令流多数据流。
图片
具体信息如下表所示。
体系结构类型 | 结构 | 关键特性 | 代表 |
单指令流单数据流(SISD) | 控制部分:一个 处理器:一个 主存模块:一个 | 单处理器系统 | |
单指令流多数据流(SIMD) | 控制部分:一个 处理器:多个 主存模块:多个 | 各处理机以异步的形式执行同一条机灵 | 并行处理机、阵列处理机、超级向量处理机 |
多指令流单数据流(MISD) | 控制部分:多个 处理器:一个 主存模块:多个 | 被证明是不可能的,至少是不实际的 | 目前没有,有资料记载流水线处理机为此类 |
多指令流多数据流(MIMD) | 控制部分:多个 处理器:多个 主存模块:多个 | 能够实现作业、任务、指令等各级全面并行 | 多处理机系统、多计算机 |
指令的基本概念
一条指令就是机器语言的一个语句,它是一组有意义的二进制代码,指令的格式如下所示。
其中,操作码部分指出了计算机要执行什么性质的操作,例如,加法、减法、取数、存数等。地址码字段需要包含各操作数的地址及操作结果的存放地址等,从其地址结构的角度可以分为三地址指令、二地址指令、一地址指令和零地址指令。
三地址指令
例如,执行a+b=c操作时,就是使用的三地址指令。此时如下所示。
图片
二地址指令
图片
例如,执行a+=b操作时,执行的就是二地址指令,此时如下所示。
图片
一地址指令
图片
例如,执行a++操作时,执行的就是一地址指令,此时如下所示。
零地址指令
例如,宕机就是零地址指令。
寻址方式
总体来说,寻址方式可以分为:立即寻址、直接寻址、间接寻址、寄存器寻址、寄存器间接寻址。
图片
- 立即寻址:操作数直接在指令中,速度快,灵活性差。
- 直接寻址:指令中存放的是操作数的地址。
- 间接寻址:指令中存放了一个地址,这个地址对应的内容是操作数的地址。
- 寄存器寻址:寄存器存放操作数。
- 寄存器内存放的是操作数的地址。
CISC与RISC
CISC和RISC分别表示复杂指令集系统和精简指令集系统,具体信息如下表所示。
指令系统类型 | 指令 | 存执方式 | 实现方式 | 其他 |
CISC(复杂) | 数量多、使用频率差别大,可变长格式 | 支持多种 | 微程序控制技术(微码) | 研发周期长 |
SISC(精简) | 数量少,使用频率接近,定长格式,大部分为单周期指令,操作寄存器,只有Load/Store操作内存。 | 支持方式少 | 增加了通信寄存器、硬布线逻辑控制为主,适合采用流水线 | 优化编译,有效支持高级编程语言 |
如何比较CISC和RISC,分哪些维度?
指令数量、指令使用频率、存执方式、寄存器、流水线支持、高级语言支持。
- CISC:复杂、指令数量多,频率差别大、多寻址。
- RISC:精简、指令数量少。操作寄存器,单周期,少寻址,多通用寄存器,流水线,
流水线概念
流水线是指在程序执行时,多条指令重叠进行操作的一种准并行处理的实现技术。各种部件同时处理是针对不同指令而言的,它们同时为多条指令的不同部分进行工作,以提高各部件的利用率和指令的平均执行速度。
流水线的相关参数计算包括:流水线执行时间计算、流水线吞吐率、流水线加速比、流水线效率。
图片
在计算机中,对于指令的操作主要分为三个部分:取指、分析和执行。如下所示。
图片
如果执行取值、分析和执行各需要1ms的话,则串行执行三条指令的时间总共需要9ms。这是因为一条执行的操作需要经过取指、分析和执行三个步骤,每个步骤需要1ms,执行一条指令的时间为3ms,则串行执行三条指令的时间为9ms。我们可以用下图来表示这个过程。
图片
在上图的表示中,貌似执行三条指令使用9ms是没啥问题的。但是,如果我们把图形改造一下,我们就会发现相应的问题。我们使用下面的图形来表示执行三条指令的情况。
此时,我们发现,在上图执行指令操作的过程中,有很多空白的格子,而空白的格子表示在执行执行的过程中有空余的时间片资源没有利用起来。
很显然,没有必要等待指令1完全执行完毕后再执行指令2,同样的,没有必要等待指令2完全执行完毕后再执行指令3。而且,我们发现按照上图执行完三条指令需要9ms时间。
此时,如果将空余的时间片利用起来,则可以使用下图来表示。
图片
此时,在执行三条指令的过程中,取指操作对指令1执行完取指后,马上对指令2进行取指,然后又马上对指令3进行取指;分析操作同样是对指令1执行完分析后,马上对指令2进行分析,然后又马上对指令3进行分析;执行操作也是对指令1执行完毕后,马上对指令2进行执行操作,然后又马上对指令3进行执行操作。期间,将空余的时间片资源充分的利用起来了。
而且,我们发现,充分利用空余的时间片后,执行三条指令的时间由原来的9ms变为现在的5ms。
从另一个角度,我们发现执行完第一条指令时,需要3ms,执行完第二条指令时,只需要在执行完第一条指令的基础上增加1ms。同样的,执行完第三条指令时,只需要在执行完第二条指令的基础上增加1ms。以后每增加一条指令,只需要增加1ms的时间便可以执行完此条指令。
这就是计算机中的流水线技术。接下来,我们就说说流水线技术的相关计算问题。
流水线计算
关于流水线计算,我们先来看一个图。
图片
在上图中,我们可以看出,执行完第一条指令时,需要3ms时间,执行完第二条指令时,只需要在执行完第一条指令的基础上增加1ms;执行完第三条指令时,只需要在执行完第二条指令的基础上增加1ms。
以此类推,执行完第n条指令时,只需要在执行第n-1条指令的基础上增加1ms。说到这里,不知道小伙伴们有没有思考这样一个问题,流水线技术的这种规律就涉及到一个非常重要的概念,叫作 流水线周期。
流水线周期为执行时间最长的一段,上图中的流水线周期为1ms
流水线的计算公式为:
1条指令执行时间 + (指令条数 -1)* 流水线周期
流水线的理论公式如下所示。
(t1 + t2 + ... + tk) + (n-1) * △t
其中t1,t2...tk表示执行一条指令的每个步骤分别需要的时间,n为指令的条数,△t为流水线周期。
流水线的实践公式如下所示。
k*△t + (n-1) * △t
其中,k为执行一条指令的步骤数,n为指令的条数,△t为流水线周期。
这里,给小伙伴们举一个例子。
例如,一条执行的执行过程可以分解为取指,分析和执行三步,在取指时间t取指=3△t,分析时间分析=2△t,执行时间t执行=4△t的情况下,若按照串行方式执行,则10条指令全部执行完需要多少△t?若按照流水线方式执行,流水线周期为多少△t?使用流水线方式时,执行完10条指令需要多少△t?
(1)串行方式比较简单,就是将每条指令的执行时间进行累加。
(3△t + 2△t + 4△t) * 10 = 90△t。
(2)在执行一条指令的过程中,取指为3△t,分析为2△t,执行为4△t。根据流水线中对于流水线周期的定义:流水线周期为执行时间最长的一段,所以,流水线周期为4△t。
(3)使用流水线方式时,执行完10条指令需要的时间可以使用如下方式进行计算。
这里,我们分别计算下理论时间和实践时间。
- 理论时间
(3△t + 2△t + 4△t) + (10-1) * 4△t = 45△t。
- 实践时间
3 * 4△t + (10-1) * 4△t = 48△t。
超标量流水线
关于超标量流水线,我们可以使用下图来表示。
图片
在超标量流水线中,有一个概念叫作度。度表示在超标量流水线中,由几条流水线组成。例如上面的图中,超标量流水线由两条流水线组成,所以,度为2。此时的超标量流水线可以同时进行2个操作。
也就是说,可以同时执行两个取指操作,可以同时执行两个分析操作,也可以同时执行两个执行操作。
如果此时有10条指令需要执行,使用以上超标量流水线的话,只需要10 / 2 = 5 条指令的时间。
流水线吞吐率计算
流水线的吞吐率(TP)是指在单位时间内流水线所完成的任务数量或输出的结果数量。计算流水线吞吐流程的最基本的公式如下所示。
图片
流水线最大吞吐率计算公式如下所示。
图片
流水线的吞吐率计算问题相对来说还是比较简单的。
层次化存储结构
首先,问小伙伴们一个问题:计算机的存储结构为什么需要进行层次化的划分呢?
说的直接一点:就是为了减少经济成本。如果说,CPU的价格非常便宜的话,根本就不需要内存了。可以把所有的内存容量全部都做到CPU里面去,就可以了。
但是,事实上,CPU的内存是很精贵的,至今为止,CPU中基本上还是一级缓存和二级缓存。三级缓存比较少见。而且,CPU中的存储容量是非常小的,基本都是KB级别的存储,CPU的内存容量也就几KB,MB级别的CPU内存也是比较少见的。所以,出于经济成本的考虑,计算机中的存储结构是按照层次进行划分的。
为了能够让小伙伴们更加清晰的理解层次化存储结构,我们先来看一张图。
图片
由上图,可以看出:
(1)层次化的存储结构可以分为:CPU、Cache(高速缓存)、主存(内存)、外存(辅存)。
(2)从上往下,速度越来越慢,容量越来越大。
局部性原理是层次化存储结构的支撑。
局部性原理
一个编写良好的计算机程序常常具有良好的局部性。也就是说。它们倾向于引用临近于其他最近引用过的数据项的数据项,或者最近引用过的数据项本身。这汇总倾向性,就被称为局部性原理,这是一个持久的概念,对硬件和软件系统的设计和性能都有着极大的影响。
之所以有这个规律,很多人认为原因是:程序的指令大部分时间是顺序执行的」,而且程序的集合,如数组等各种数据结构是连续存放的。
局部性原理讲的是:在一段时间内,整个程序的执行仅限于程序的某一部分,相应地,程序访问的存储空间也局限于某个内存区域。主要分为两类:
图片
- 时间局部性:如果程序中的某条指令一旦执行,则不久之后该指令可能再次被执行;如果某数据被访问,则不久之后该数据可能再次被访问。
- 空间局部性:是指一旦程序访问了某个存储单元,则不久之后,其附近的存储单元也将被访问。
Cache
针对Cache相关的技术,我们主要来聊聊Cache的概念和映像相关的技术。
Cache-概念
这里的Cache表示的是高速缓冲,在计算机的存储体系系统中,Cache是除寄存器外访问速度最快的层次。使用Cache改善系统性能的依据是程序的局部性原理 。
如果以h代表对Cache的访问命中率,t1表示Cache的周期时间,t2表示主存储器的周期时间,以读操作为例,使用“Cache+主存储器”的系统的平均周期为t3,则可以得出如下运算公式。
t3 = h * t1 + (1 - h) * t2
其中。(1 - h)又称为失效率,也就是未命中率。
Cache-映像
Cache的映像分为三种,分别是:直接相联映像、全相联映像、组相联映像。
图片
- 直接相联映像:硬件电路比较简单,但冲突率最高。
- 全相连映像:电路难于设计和实现,只适用于小容量的Cache,冲突率比较低。
- 组相联映像:直接相联与全相联的折中。
地址映像是将主存与Cache的存储空间划分为若干大小相同的页(或称为块)。
例如,一台计算机的主存容量为1GB,划分为2048页,每页512KB;Cache的容量为8MB,划分为16页,每页512KB。接下来,我们由此来详细图解直接相联映像、全相联映像和组相联映像。
直接相联映像
我们可以画一组图来表示Cache的直接映像。首先,我们先来简单画一个主存标记、Cache页号和页内地址的示意图。如下所示。
图片
如上图所示,主存标记为7位,Cache页号为4位,页内地址为19位。
记录主存区号的示意图如下所示。
图片
有了上面两张图的基础后,我们再来看直接相联映像的示意图如下所示。
图片
这里,我们将容量为1GB的主存划分成2048页,总共127个区,每页的容量为512KB。将容量为8MB的Cache划分为16页,每页容量为512KB。
所谓直接相联映像是指Cache中的0页只能存储主存中0页的内容,这里主存中0页指的是每个区的0页,比如上图中的0区的0页,1区的16页,127区的2032页等。
在直接相联映像中,只需要记录主存标记、Cache页号和页内地址就能够快速的找到主存中的数据。
使用直接相联映像有个缺点:那就是如果Cache中的0页,存储了主存中0区0页的内容时,如果此时需要存储主存1区中的16页内容,就只能将主存0区中0页的内容从Cache的0页中清除,然后将主存1区中16页的内容存储到Cache中的0页内。冲突率比较高。细心的小伙伴会发现:这其实是违背局部性原理的。
直接相联映像访问速度最快,但冲突率最高。
全相连映像
我们先来看下全相联映像的主存页标记和页内地址的示意图,如下所示。
图片
此时,使用11位来标识主存页标记,使用19位来标识页内地址。
使用全相连映像需要记录主存与Cache的对应关系,如下图所示。
图片
接下来,我们来看看全相连映像的示意图,如下所示。
图片
从图中可以看出,Cache中的任何一个也,都可以存储主存中的任何一个页。
使用全相连映像访问速度最慢,冲突率最低。
组相联映像
组相联映像本质上是直接相联映像和全相联映像的折中。同样的,我们先来看组相连映像的存储示意图。
图片
此时,在组相连映像中,Cache组号使用3位表示,组内页号使用1位表示,页内地址使用19位表示。其中,3位的Cache组号,1位的组内页号和前面的7位构成了主存页标记;3位的Cache组号,1位的组内页号和19号的页内地址构成了Cache地址。
接下来,我们再来看看主存与Cache的对应关系,如下图所示。
图片
组相连的映像示意图如下所示。
图片
由上图可知,在组相连映像中,主存的组与Cache的组是组相联映像关系,而在组内则是通过直接相联映像来访问和存储数据。
主存编址与计算
这里,小伙伴们首先要区分两个概念,一个是编址,一个是寻址。
编址: 存储器是由一个个存储单元构成的,为了对存储器进行有效的管理,就需要对各个存储单元编上号,即给每个单元赋予一个地址码,这叫编址。经编址后,存储器在逻辑上便形成一个线性地址空间。
寻址:存取数据时,必须先给出地址码,再由硬件电路译码找到数据所在地址,这叫寻址。
编址可以分为两种:按字编址和按字节编址。
图片
- 按字编址:存储体的存储单元是字存储单元,即最小寻址单位是一个字。
- 按字节编址:存储体的存储单元是字节存储单元,即最小寻址单位是一个字节。
对于主存编址中最常见的计算形式为:根据存储器所要求的容量和选定的存储芯片的容量,就可以计算出所需要的芯片的数量。公式如下所示。
总片数 = 总容量 / 每片的容量
这里,给小伙伴们举一个例子:若内存地址区间为4000H ~ 43FFH,每个存储单元可存储16位二进制数,该内存区域使用4片存储器芯片构成,则构成该内存所用的存储器芯片的容量是多少?
解题思路也比较简单,我们一起来看看如何解题:
(1)首先,我们来求解4000H ~ 43FFH地址空间的总容量,使用终止地址-起始地址+1即可得到总容量,也就是43FFH - 4000H + 1 = 43FFH + 1 - 4000H = 4400H - 4000H = 400H。
注意:在计算机中,以H结尾的数字是十六进制,逢16进1,而F在十六进制中表示15,所以,43FFH + 1 = 4400H。
所以,4000H ~ 43FFH地址空间的总容量为400H。
(2)接下来,我们要把400H转换成二进制,对于十六进制数转换成二进制数来说,每一位十六进制数对应着四位的二进制数,我们可以把400H拆分成4、0、0三部分,4转换成二进制数就表示0100,十六进制的0转换成二进制为0000。所以,400H转换成二进制的结果为:0100 0000 0000。
0100 0000 0000也就是2的10次方,即为2^10^。
(3)题目中说的每个存储单元可存储16位二进制数,所有总共可以存储的二进制数就是:2^10^ * 16。
(4)该区域使用4片存储器芯片构成,所以,存储芯片的容量为:2^10^ * 16 / 4 = 2^10^ * 4 = 2^12^,最终的结果单位为bit。
总线
一条总线同一时刻只允许一个设备发送数据,但允许多个设备接收数据。
总线的分类
总线可以分为数据总线、地址总线和控制总线。
图片
- 数据总线(Data Bus):在CPU和RAM之间来回传送需要处理或是需要存储的数据。
- 地址总线(Address Bus):用来指定在RAM(Random Access Memory)之中存储的数据的地址。
- 控制总线(Control Bus):将微处理器控制单元(Control Unit)的信号传送到周边设备,一般常见的为USB Bus和1394 Bus。
串联系统与并联系统
这里,先给小伙伴们简单介绍下什么是串联系统,什么是并联系统。
串联系统
串联系统是组成系统的所有单元中任一单元失效就会导致整个系统失效的系统。把用电器各元件逐个顺次连接起来,接入电路就组成了串联电路。我们常见的装饰用的"满天星"小彩灯,常常就是串联的。
串联电路有以下一些特点:
⑴电路连接特点:串联的整个电路是一个回路,各用电器依次相连,没有"分支点"。
⑵用电器工作特点:各用电器相互影响,电路中一个用电器不工作,其余的用电器就无法工作。
⑶开关控制特点:串联电路中的开关控制整个电路,开关位置变了,对电路的控制作用没有影响。即串联电路中开关的控制作用与其在电路中的位置无关。
注:以上对于串联系统的描述来源于网络。
接下来,我们来看一个关于串联系统的图形表示,这里我们假设串联系统中每个部分的可靠度依次为R1,R2,...Rn,如下所示。
图片
则整个系统的可靠度为:R = R1 * R2 * ... * Rn。
并联系统
并联系统指的是组成系统的所有单元都失效时才失效的系统。把电路中的元件并列地接到电路中的两点间,电路中的电流分为几个分支,分别流经几个元件的连接方式叫并联。
并联电路是使在构成并联的电路元件间电流有一条以上的相互独立通路,为电路组成二种基本的方式之一。例如,一个包含两个电灯泡和一个9 V电池的简单电路。若两个电灯泡分别由两组导线分开地连接到电池,则两灯泡为并联。
即若干二端电路元件共同跨接在一对节点之间的连接方式。这样连成的总体称为并联组合。其特点是:
①组合中的元件具有相同的电压;
②流入组合端点的电流等于流过几个元件的电流之和;
③线性时不变电阻元件并联时,并联组合等效于一个电阻元件,其电导等于各并联电阻的电导之和,称为并联组合的等效电导,其倒数称为等效电阻
注:以上对于并联系统的描述来源于网络。
接下来,我们来看一个关于并联系统的图形表示,这里我们假设并联系统中每个部分的可靠度依次为R1,R2,...Rn,如下所示。
图片
则整个并联系统的可靠度R = 1 - (1 - R1) * (1 - R2) * ... * (1-Rn)。
混合型系统
混合型系统就是既有串联系统,又有并联系统的系统,这里,我们也使用一个图形进行表示,如下所示。
图片
所以,上图并联系统的可靠度为:R * (1 - (1 - R) ^3^) * (1 - (1 - R) ^2^)