计算机系统基础--第五章(程序的执行)

按照ISA的复杂程度而言,有复杂指令集(CISC)和精简指令集(RISC)两种类型的计算机。而intel就是属于前者

程序执行的概述

指令周期:CPU取出并执行一条指令的时间成为指令周期,不同指令的周期时间可能不同。
执行程序顺序:

1
2
3
4
5
6
1、取指令:从pc所支出的存储单元取出指令送到指令寄存器
2、指令译码:例如,mov $0x0,%eax,将立即数送到寄存器ebp中
3、计算源操作数地址并取操作数:根据寻址方式确定源操作数地址计算方式,若是存储器数据,则最多一次
4、执行数据操作:在ALU或加法器等运算部件中取出的操作数进行计算
5、计算目的操作数地址并存结果:根据寻址方式确定目的操作数地址计算方式,若是存储器数据,则最多一次,若是寄存器数据,则在进行数据操作时直接存结果到寄存器
6、计算下一条指令地址:顺序执行时,将pc加上当前指令长度即可。如果是转移类指令时,需要根据条件标识、操作码和寻址方式确定下一条指令

基本操作:

1
2
3
4
1、读取某储存单元内容(可能是指令或操作数或操作数地址),并将其装入某个寄存器。
2、把一个数据从某个寄存器存储到给定存储单元。
3、把一个数据从某个寄存器传送到另一个寄存器或ALU。
4、在ALU中进行某种算术运算或逻辑运算,并将结果送到某个寄存器中。

cup的基本功能和组成

由程序计数器(PC),指令寄存器(IR),指令译码器(ID),脉冲源及起停控制逻辑,时序信号产生部件,操作控制信号形成部件,总线控制逻辑,终端机构组成

打断程序正常执行的事件

1、内部异常:源自于正在运行程序本身,来自于cpu内部。是必然,同步事件。
2、外部中断:源自于正在运行程序的条件,来足浴cpu外部,是偶然,异步事件。

数据通路基本逻辑和工作原理

操作元件:多路选择器(MUX),加法器(ADDER),算术逻辑部件(ALU),译码器(Decoder)
状态元件:D触发器,这需要建立时间以及保持时间,也称触发器的锁存延迟。
数据通路的时钟周期:cycle Time = clk-to-Q(稳定时间)+Longest Delay(处理时间)+ 建立时间+时钟偏移。
工作原理:
simpleBus
数据通路中的部件之间可以通过总线方式连接,ALU及所有的寄存器通过一条内部的公共总线连接起来,已构成单总线结构数据通路,因为在cpu内部成为cpu内总线。
1、完成算术或逻辑运算

1
2
3
4
其完成R[R3]<-R[R1]+R[R2]操作如下:
1、R1(out),Y(in)
2、R2(out),add,Z(in)
3、Z(out),R3(in)

2、从内存读取一个字(指令或数据或数据的地址)

1
2
3
4
其完成R[R2]<-M[R[R1]]操作如下:
1、R1(out),MAR(in)
2、read,WMFC(使cpu进行等待)
3、MAR(out),R2(in)

3、把一个字(数据)写入内存

1
2
3
4
其完成M[R[R2]]<-R[R1]操作如下:
1、R1(out),MDR(in)
2、R2(out),MAR(in)
3、write,WMFC

流水线方式下命令的执行

想象以下,你有一堆衣服,有洗,甩干,晾三个操作,分别时间是40,30,20。有洗衣机和甩干机,晾必须得自己操作,当然,洗衣间衣服的时间是40+30+20,若洗n件衣服,依然还是使用这种算法,则总时间为n(40+30+20),而我们最好的方法是:

在洗第n件衣服时,正好在甩干第n-1件,在晾第n-2件。而大家都同时以40分钟时间为标准,因此。最后的总时间为:40n+30+20,节省不少时间。
在计算机中也是如此,设计原则是:
指令流水段个数以最复杂指令所用的功能段数为准,流水段的长度以最复杂的功能段的操作所用的时间为准。
因此,比较适合流水线的指令集特征为:
1、指令长度尽量一致。
2、指令格式尽量规整,尽量保证源寄存器的位置相同
3、采用load/store型指令风格(指令集中只有load指令和store指令能访问内存储器,其他一律不行)
4、数据和指令要在寄存器中“对齐存放”

流水线方式下出现问题

1、结构冒险:可能逻辑A与逻辑D存放的正好是同一个寄存器,而同时需要运行这条指令,造成结构冒险,由于硬件共享产生的问题。
解决方案:
(1)、规定一个部件的每条指令只能使用一次,而且只能特定阶段使用
(2)、通过设置多个独立的部件来避免资源的冲突

2、数据冒险:后面的指令用到前面指令的运算结果,前面的指令还没有完成,结果还没有算出,造成数据冒险。
解决方案:
(1)、由编译器在数据相关的指令之间加若干个nop(空操作指令)指令,等待上一条数据的产生
(2)、采用数据转发机制,即结果出来后通过旁路放到相关的exce阶段的ALU输入端
(3)、通过硬件阻塞(插入气泡)来延迟load命令执行
(4)、通过寄存器的读写操作进行特殊处理,保证在一个时钟的前半周期进行寄存器写,在后半期进行寄存器读。

3、控制冒险:
由于中断或转移指令的执行顺序,可能发生控制冒险。
可通过插入气泡或插入空操作符解决。

小结:

计算机程序的运行并没有那么简单,从简单的代码,转化为汇编之后,再变成单条的运行,之间发生了奇妙的变化,这章的学习让我明白软件的运行并不是简单我们看到的代码,而是分解之后单条单条的汇编代码,每条汇编代码又需要执行条小周期,才能完成一条汇编代码。而每条小周期还能变成一个完整的流水线。即使每个流水线都是有各种各样的问题,但解决流水线问题之后,速度是质的提升。这种思想也改变了我的思维,对代码效率的考虑。