第1章 计算机系统概述
1.1 计算机发展历程
1.1.1 计算机的产生
计算机基础理论80多年了,关键部件还没有大变化。CPU(运算器控制器),存储器,输入输出。
1945 冯诺依曼《电子计算工具逻辑设计》,提出二进制表示方式和存储程序控制计算机构想。
1946 ENIAC宾夕法尼亚大学 5000次/s 20个寄存器10位十进制 第一台通用电子计算机
第一个小型计算机56PDP-1 12w美元卖了50台 第一个系列计算机IBM360 相同的系统结构
1.1.2 电子计算机的发展简史
电子管时代46-58:定点计算,机器语言,汇编语言
晶体管时代58-65:集中处理变成分级处理,浮点运算,高级语言
中小规模集成电路65-70:存储容量大,运算速度快
大超大规模集成电路71-90:分化出大型机和微型机两种方向
甚大规模集成电路90-0x:单片集成1million晶体管
极大规模集成电路0x-xx:1-10亿晶体管单片
现代计算机发展方向:巨型化,微型化,网络化,智能化,多核处理
电晶小中大,定浮集成化
通用微处理器发展历程
第一代71-73:4位or8位微处理器比如intel4004和8008,微处理器指令系统不完整,存储容量小只有汇编程序,没有操作系统,4kb内存。
第二代74-77:intel8080和8085,集成度提高,位增多,具有了中断、直接存储器存取等功能。
第三代78-84:16位微处理器8086,1Mb内存。 80286外部传输16位内部24位,内存寻址16mb
第四代85-92:32位处理器80386 80486
第五代93-05:奔腾处理器64位 0.18-0.5微米级 120Mhz-2Ghz 二级缓存 多CPU
第六代05-now:酷睿处理器 纳米级 多核多线程 三级缓存 多通道内存 2.66 2.93 3.2Ghz
趋势:从单处理器向多处理器发展
提高计算机性能方法
发展方向:并行处理
· 对传统结构改造,采用多个处理部件形成流水线处理,依靠时间重叠提高处理效率。or阵列机结构,单指令流多数据流,提高处理速度。
· 多个诺伊曼机组成多机系统,并行算法
· 根本上改变冯诺依曼机的控制流驱动方式。比如采用数据流驱动,只要数据备好,相关的指令就可以并行执行。
1.1.3 计算机的分类
巨型机:超级计算机
大中型机:大中型企业的计算中心,统一调度主机资源
小型机:小型企业部门需求
工作站:图形处理辅助设计等特殊领域
微型机:PC/个人计算机
1.2 计算机系统层次结构
1.2.1 计算机系统硬件组成
典型的冯诺依曼机由输入设备,存储器,运算器,控制器,输出设备组成。
控制器可以向其他四个设备发送控制信号,但和其他设备间没有数据线路。存储器运算器之间通过数据线路交流,他们和控制器间也有单向数据线路。
早期运算器和控制器分为两部分,现在集成在CPU内。
运算器:完成数据暂存、变换、算术运算和逻辑运算
控制器:完成对计算机各部件协同指挥控制,保证指令依次执行。
存储器:存放程序和数据,是计算及各种信息的存储和交流中心。可以和CPU、输入输出设备交换信息。
输入设备:输入原始数据和处理这些数据的程序。可以输入数字、字母、控制符。
输出设备:输出计算机处理结果,可以是数字字母等各种形式。
IO存运控,运算是中心。运控一合并,信号向外传。
冯诺依曼机基本特点
1、5部分组成
2、二进制代码标识程序和数据
3、采用存储程序的工作方式:程序和数据存放在同一存储器中,由指令组成的程序进行修改。
4、指令在存储器中循序存放,指令计数器指明执行指令所在的单元地址,一般按顺序递增。
5、以运算器为中心,数据传送都经过运算器。
总:存储程序、并按照地址顺序执行是冯诺依曼计算机设计的关键思想。
1.2.2 计算机软件组成
软件按照面向对象的不同可分为系统软件和应用软件
系统软件:面向系统,管理计算机系统,合理分配系统资源。确保计算机正常高效运行。操作系统就是系统软件,此外还有汇编程序,编译或解释程序,故障诊断or检验程序,系统调试程序和数据库管理程序。
应用软件:用来实现用户的某类特殊需求。使用者采用各类语言编写的各种应用程序。
汇编、编译、诊断、调试、数据、操作系统 汇诊调数编操
计算机语言简洁
自然语言、机器语言、汇编语言(符号式设计语言 低级语言)、高级语言(与自然语言接近)、机器语言(由二进制代码表示的指令组成)
1.2.3 计算机系统的层次结构
计算机是个复杂的软硬件综合体,它通常有6or5个不同的级组成,在每一级都能进行程序设计——虚拟机。
硬件级:逻辑部件级(硬件逻辑部件)微程序级(微程序控制器)
软件级:传统机器级(指令系统)操作系统级(操作系统)汇编语言级(系统程序)高级语言级(应用程序)
站在不同层次上编程的程序员所看到的计算机属性各不相同(不透明化)。
软件硬件逻辑上的等价性
计算机中有些功能软硬件都可以处理,硬件处理速度高一点儿,软件成本低一点儿。硬件和软件基本可以等价。
兼容性
新机型要求兼容老机型上开发的软件,还有硬件上的兼容要求。兼容要求软件和硬件设备在不同的机型上使用。
1.3 计算机性能指标
1、基本字长
表示一个操作数或一条指令所用的基本二进制位数
它是CPU一次能处理的数据宽度,与加法器,寄存器的位数和内部数据总线的宽度有关
字长标志着精度,通常字长越长,运算精度越高。
影响计算机的处理能力和运行性能。
通常选字节的整数倍:2、4、8、16、32、64
2、运算速度
反应运算快慢,有不同的衡量方法
1、统计平均值求出平均运算速度
2、直接给出每条指令的实际执行时间
MIPS和MFLOPS等作为计量单位:MIPS每秒百万条指令 MFLOPS每秒百万次浮点运算
还有TFLOPS PFLOPS等
响应时间:从时间开始到结束的时间又称为执行时间
主频:计算及内部都有个不断产生固定频率时钟脉冲的装置,称为主时钟,CPU工作主时钟的频率通常是机器的主频,是衡量一台计算机速度的重要参数。用Fc表示。
CPU的时钟周期:主频的倒数Tc,Tc=1/Fc
CPI:Cycle Per Instruction 执行一条指令所需要的平均时钟周期数
公式部分:
CPU执行之间:Tcpu=In*CPI*Tc In表示执行程序中指令的总数
MIPS:CPU每秒钟平均执行的整数指令条数(百万条)
MIPS=In/(Tcpu*10^6)=Fc/(CPI*10^6)
注意:MIPS只适合评价标量机,不适合评价向量机。
标量机执行一条指令得到一个运行结果;向量机得到多个运算结果。
CPI还可以表示为CPI=sigma CPIi *(Ii/In) Ii/In表示第i类指令在所有程序指令中所占的比例
如果想要评价向量机用MFLOPS
MFLOPS=Ifn/(Tcpu*10^6) lfn:程序中浮点数的运算次数
一般同一程序运行在不同的计算机上往往会执行不同数量的指令数,但是所执行的浮点运算次数常常是相同的。
3、存储容量
反映计算机能够存取的数据规模,包括主存容量和辅存容量
主存容量:主存中存放的二进制代码的总位数
主存容量=存储单元个数*存储字长
现代计算机使用字节数描述存储容量的大小
1字节=8位二进制代码 主存基本就是指内存,辅存指硬盘等
第2章 数据的表示和运算
2.1 数制与编码
计算机内部信息都以数字化形式存储加工传送,不同信息通过编码表示。编码:用少量简单基本符号,对大量复杂多样信息进行一定规律的组合表示。需要解决的问题:
1、用什么数制 2、数的符号表示(原反补) 3、小数点的表示(定浮)
二进制编码优点:
1、物理上容易实现 2、表示数值数据运算规则简单 3、与二值逻辑的真假两个值对应简单
2.1.1 进位计数制及其相互转换
1.进位计数制
基数,权值。基数是数字符号个数,权是数字所在位的相关系数常数。
计算机中使用2 8 10 16四种进制。2进制用于内部,8 16进制用于缩写,10进制给人看。
2、转换
10进制转换n进制方法:除2取余 乘2取整
2进制转8 16进制:缺位整数补高位,小数补低位
2.1.2 数值数据的编码与设计
数值数据:有确定值的数据。
确定要素:进位计数值,定点or浮点,编码表示。
表示方法:BCD码(二进制编码十进制数表示)or直接二进制数表示
正负号是首要问题!
符号数字化,0表示正,1表示负。机器数是机器中的数值表示,真值相反。
1、BCD码
简单说就是用二进制数和十进制数转换来编码。用4位二进制位最多表示16个十进制数。编码方案有有权和无权之分,8421码是最常见的BCD码。无权码也是一种,比如余3码和格雷码。
BCD码加法运算修正:相加之和大于9或者产生进位,如果加6修正。如果有进位,需要向高位进位。BCD码消耗资源多,冗余了6个数,不太好。
2.1.3 非数值数据的表示
1、逻辑数据的编码
1真0假,按位进行运算。逻辑数据和数值数据在形式上无差别,机器本身不能识别,需要指令来识别。
2、字符的编码表示
英文字符总数不超过256个,所以使用7or8位二进制位就可以表示。ASCII码用7位二进制表示一个字符,共128个字符
2.1.4 校验码
为了提高计算机可靠性,可以从数据编码上想办法。
采用冗余线路,在原有数据位外增加校验位,使新得到的由数据位和校验位构成的码字带上某种特性。经过薄弱环节后可以通过校验位判断码字值是否出错。定位错误后甚至可以自动纠错。
概念:校验位,码字,码制,距离(将两个码字逐位比较,具有不同代码的位的个数,叫做这两个码字的距离。码距:将一种码制中各码字间的最小距离称码距。合理增大码距能提高发现错误的能力,但增加了电子线路的复杂性和数据存储与运算量。)
常用的校验码:
1、奇偶校验码:用于并行数据传输
2、海明校验码:用于并行数据传输
3、循环冗余校验码:用于串行数据传输
运行过程3部曲:
原始数据形成校验位加入特征,传送码字,检查收到的码字,发现并改正错误。
1、奇偶校验码
原理:使码距从1增加到2。若编码中有一位2进制数出错了,出错的就是非法编码。在原编码上增加1位使k位编码变成了k+1位编码。奇校验:保证编码中1的个数是奇数。偶校验/偶。
特点:只能对奇数位长度出错进行检测,码距为2时校验位不变检查不出来。不具备纠错能力。
优点:开销小。常用于存储器读写检查or按字节串书中的数据校验。
2、循环冗余校验码CRC
原理:k为信息之后拼接r位校验码,用带有xor控制的移位寄存器形成r个校验位的值。跟随在数据位之后传送走。
特点:可以自动纠错,什么情况都能检查出来。
2.2 定点数的表示和运算
小数点的位置固定。常规计数996.007 科学计数 9.96007*10^2
定点数分为1、有符号数 2、无符号数
有符号数又可以分为4种 1、原码 2、反码 3、补码 4、移码
2.2.1 无符号数的表示
整个及其字长都是数值位,没有符号位。相当于绝对值。
注意 表示范围:8位:0~255 0~(2^n)-1
通常只谈讨整数无符号数,小数无符号数不讨论。(unsigned float会报错的)
2.2.1 有符号数的表示(原补反移)
定点整数:符号位+数值位+小数点位置(隐含)
定点小数:符号位+小数点位置(隐含)+数值位(尾数)
原码:尾数表示真值绝对值,符号位0正1负。常写为:[x]原=1,0010011 [x]原=1.1100000
真值0有两种表示形式。
表示范围:定点整数:-(2^n-1)<=x<=2^n-1 (关于原点对称)共表示2^n-1个数(0有两个)
定点小数把n换成-n即可。
反码:如果符号位为0,反码原码相同;如果符号位1,符号位不变,数值位全部取反即可。
表示范围与原码相同。
补码:正数补码=原码,负数补码=反码末尾+1(考虑进位)
注意+0补码是00000000,-0补码100000000,最高位1被干掉,还是00000000
所以定点数补码的0只有一种表示方法!,那么10000000用来表示什么呢?我们规定这里最高位表示符号,即-2^7.
表示范围:定点整数:-2^n-<=x<=2^n-1 比原码反码多了一个-2^n
定点小数:-1<=x<=1-x^-n 10000000用来表示-1,比原码反码表示范围多了这个-1。
移码:只能用于表示整数,不能表示小数。
补码基础上把符号位取反。移码的+0 -0只有一种表示形式10000000.
表示范围:与补码相同。
特性:移码表示的整数方便比较大小,随着移码编码的增大,真值也增大。从最高位向下比,谁最高位先出现1谁更大。
2.2.2 原补移反的作用
补码:
对于加法 00001110+10001110=10011100:对于无符号数成立,对于有符号数要10001110改变成减去00001110,算数逻辑器也必须配置加法器和减法器(减法器电路比较难)。这时候一群大聪明想出了个方法用加法代替减法。
负数mod:-3 mod 12=9;9 mod12 =9所以-3==9,mod12余数相同的数都是等价的。我们发现,在mod m的条件下,如果能找到负数的补数(两个数同时满足mod相同和两者绝对值之和=mod数),就可以用正数的加法替换减法。对于8bit计算机而言,8b一个1byte,要将所有的数字都映射到8b里面,相当于mod2^8。这是计算机内部的一个运算的隐含条件。补码可以将减法操作转变为加法操作,ALU中无需集成减法器,符号位一起参与运算。节省硬件成本。《数论》
反码其实是原码到补码之间的中间状态。没啥特别的意义。
移码方便比大小用的。
2.2.3 移位运算
定点数的运算通过移位运算,加减运算,乘法除法运算得到。
算数移位、逻辑移位、循环移位。
算数移位就是*进制^n其实就是改变小数点的位置。10010100->10001010相当于/2
对于原码:
原码右移相当于/2低位为0舍弃没有问题;如果低位不为零会丢失精度
原码左移相当于*2,高位舍弃。如果高位不为0,会出现严重误差
对于反码:
正数的反码与原码相同,因此对正数反码的位移运算也和原码相同。
负数来说,右移高位补1,左移低位补1
对于补码:
正数和原码相同。
对于负数,相当于反码末位+1,导致反码最右边几个1都变成0,直到碰到第一个0为止。
2.2.4 加减运算和溢出与符号扩展
原码的加减运算,符号位不参与运算。减法转变成加法进行。加法时符号位要判断两者的绝对值大小。
补码的加减运算,符号位同样参与运算。负数补码到原码转换时:左右边的1及右边同原码,左边数值位取反。接下来我们考虑一个溢出的问题:
00001111+01111100=10001011,两个正数相加居然变成负数了???所以计算机硬件提供了溢出处理:如果两个正数相加一定上溢出,一定是正+正=负;如果两个负数相加一定下溢出,一定负+负=正。
方法:采用一位符号位。设A的符号是As,B的符号是Bs,运算结果是Ss,溢出逻辑表达式:V=AsBsSs反+As反Bs反Ss,如果V=0没有溢出,如果V=1表示溢出。+是或运算,AsBs中间是与运算。
或者通过数据位进位情况判断溢出。分别关注符号位进位Cs和最高数值位的进位C1,01上溢,10下溢。即Cs和C1不同时发生溢出。使用异或判别。
或者采取双符号位(mod4补码),左边一位是应该是,右边一个是实际。如果01上溢,如果10下溢。
如果将int转变为long,需要进行符号扩展
对于正整数、正小数,原补反都是一样的;对于负整数:在原符号位和数值位中间添加0,反码补码添1。对于负小数,在原符号位和数值位后面添加新位数,原码补码添0,反码添1.
2.2.5 原码补码的乘法
我们小学的时候都学过多位乘法,对于2进制的乘法也是一样的。那我们如何用机器实现呢?
我们有3个问题:实际数字由正负,符号位怎么处理?乘积位数扩大一倍,怎么处理?4个位积都要保存在4个寄存器里来统一相加吗?
对于原码的乘法:
首先处理符号位,只要将两个符号位进行xor操作即可。
我们来看一下运算器里面是啥东西:
运算器用于实现算数运算,逻辑运算。ACC累加器存放操作数或运算结果,MQ乘商寄存器,Z通用操作数寄存器,ALU通过内部复杂电路实现算术运算。在乘法运算中,ACC存放乘法高位,MQ存放乘数和乘积低位,X存放被乘数,所有寄存器统一都是n+2位。MQ中的乘数慢慢移出,结果由ACC和lMQ共同表示。MQ中的最低位辅助位用来判定现在要加上什么。
对于补码的乘法Booth算法:(比原码最后多来一次加法)
相比于原码的逻辑右移,补码进行的是算数右移;补码的符号位要参与运算,原码不用。采用双符号位进行补码运算,算数移位要根据当前MQ中的最低位,辅助位来确定加什么比较好,对于补码乘法而言,是辅助位-MQ最低位。如果是0直接加上补码,如果是0不动作,如果是-1加上-x的补码。ALU中有一个取负电路可以快速算出-x是多少。最后还需要进行一轮加法结束,而原码的乘法不需要进行这样的加法,最后一轮位移后直接结束了。
2.2.6 定点数的除法
小学的时候我们做除法列竖式,乘出来的要尽可能接近当前的余数又不超过他。二进制其实是一样的。
对于原码的除法(恢复余数法):
首先符号位同样是异或操作 数值位取绝对值进行除法运算
接着数值位需要准备被除数,除数,除数补码和其负数的补码(方便相减)。ACC MQ 通用寄存器里面的内容如下:
MQ的最后一位是当前要确定的商。比较ACC和通用寄存器里面的数,如果ACC更大那就应该商1,如果小就0.但是计算机比较傻,先默认商1(减掉除数),如果搞错了(减出来ACC首位是1)在改为0并恢复余数(加上除数)。
接着ACC和MQ逻辑左移,迭代运算。
对于原码的除法优化(加减交替法):
恢复余数方法有点儿傻,其实在发现搞错了以后我们也可以不恢复余数,看下面这个过程
这种方法 在最后一步如果发现是负的也需要恢复余数
总共加减操作n+1次,每次加减确定一位商;左移n次(最后一次做完不左移)最终可能多一次加。这里我们探讨的都是定点小数的除法,并规定除数要大于被除数,因为这样整数位才是0,如果整数位>1,定点小数就没法表示了。正常情况下第一次除法一定要是负的才行,否则硬件电路就会对这种定点数除法喊停。
对于补码的运算(加减交替法):
补码的符号位也会参与运算,也跟乘法一样采样双符号位的方式表示数据。
相比乘法更加简单的判断是否加or减。并且对于末位商的处理也很有灵性。
2.2.7 强制类型转化
补充一下C语言的强制类型转化
2.2.8 数据的排列与存储模式
大小端模式:
大端方式更便于人类阅读,将高位MSB存放在低地址;将低位LSB存放在高地址。小端方式反过来,更便于机器处理。
边界对齐:
现代计算机按照字节编址,每个字节对应一个地址。但通常也支持按照字,半字,字节寻址。假设存储字长为32位,1个字=32bit,半字=16bit,每次访存只能读写一个字。
空间换时间的策略,比如下面这种情况 ,边界对齐方式空间占用大,但是访问一个字、半字都只需要一次访存;而边界不对齐的方式,虽然有效利用了空间,但也导致了访问一个字、半字可能需要两次访存的问题。
2.3 浮点数的表示和运算
2.3.1 浮点数的表示
定点数是有极限的,不同长度的需要不同的定点数格式long啊short啊。如果使用科学计数法,是不是就无敌了呢?
上面这个例子中阶码的底是10,我们在后续的研究中默认阶码的底是2(当然4,8,16啥的也可以作为底来使用)
阶码反映了浮点数的表示范围和小数点的实际位置;尾数M的数值部分的位数n反映浮点数的精度。