大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。
Jetbrains全系列IDE稳定放心使用
现代计算机由三大部分组成(已经转化为以存储器为中心)
1. CPU(Central Processing Unit) 中央处理器,核心部件为ALU(Arithmetic Logic Unit,算术逻辑单元)和CU(Control Unit,控制单元)
2. I/O设备(受CU控制)
3. 主存储器(Main Memory,MM),分为RAM(随机存储器)和ROM(只读存储器)
//CPU与MM合成主机,I/O设备可称为外部设备
二、一条指令在CPU的执行过程
// 专业术语
1. Ad(Address) 形式地址
2. DR(Data Register) 数据寄存器
3. AR(Address Register) 地址寄存器(MAR)
4. IR(Instruction Register) 指令寄存器
5. BR(Buffer Register) 缓冲寄存器(MBR)
5. ID(Instruction Decoder) 指令译码器
6. PC(ProgramCounter) 程序计数器
计算机的CPU,其工作都可以分为5个阶段:
1.取指令阶段
取指令(Instruction Fetch,IF)阶段是将一条指令从主存中取到指令寄存器的过程。
程序计数器PC中的数值,用来指示当前指令在主存中的位置。当一条指令被取出后,PC中的数值将根据指令字长度而自动递增:若为单字长指令,则(PC)+1àPC;若为双字长指令,则(PC)+2àPC,依此类推。
//PC -> AR -> Memory
//Memory -> IR
2.指令译码阶段
取出指令后,计算机立即进入指令译码(Instruction Decode,ID)阶段。
在指令译码阶段,指令译码器按照预定的指令格式,对取回的指令进行拆分和解释,识别区分出不同的指令类别以及各种获取操作数的方法。
在组合逻辑控制的计算机中,指令译码器对不同的指令操作码产生不同的控制电位,以形成不同的微操作序列;在微程序控制的计算机中,指令译码器用指令操作码来找到执行该指令的微程序的入口,并从此入口开始执行。
// { 1.Ad
//Memory -> IR -> ID -> { 2.PC变化
// { 3.CU(Control Unit)
3.访存取数阶段
根据指令需要,有可能要访问主存,读取操作数,这样就进入了访存取数(Memory,MEM)阶段。
此阶段的任务是:根据指令地址码,得到操作数在主存中的地址,并从主存中读取该操作数用于运算。
//Ad -> AR -> AD -> Memory
4.执行指令阶段
在取指令和指令译码阶段之后,接着进入执行指令(Execute,EX)阶段。
此阶段的任务是完成指令所规定的各种操作,具体实现指令的功能。为此,CPU的不同部分被连接起来,以执行所需的操作。
例如,如果要求完成一个加法运算,算术逻辑单元ALU将被连接到一组输入和一组输出,输入端提供需要相加的数值,输出端将含有最后的运算结果。
//Memory -> DR -> ALU
5.结果写回阶段
作为最后一个阶段,结果写回(Writeback,WB)阶段把执行指令阶段的运行结果数据“写回”到某种存储形式:结果数据经常被写到CPU的内部寄存器中,以便被后续的指令快速地存取;在有些情况下,结果数据也可被写入相对较慢、但较廉价且容量较大的主存。许多指令还会改变程序状态字寄存器中标志位的状态,这些标志位标识着不同的操作结果,可被用来影响程序的动作。
//DR -> Memory
6.循环阶段
在指令执行完毕、结果数据写回之后,若无意外事件(如结果溢出等)发生,计算机就接着从程序计数器PC中取得下一条指令地址,开始新一轮的循环,下一个指令周期将顺序取出下一条指令。
//重复 1~5
//遇hlt(holt on)停止
java代码是否一定按顺序执行?
这个问题听起来有点蠢,串行的代码确实会按代码语意正确的执行,但是编译器对于代码本身的优化却并不一定会按实际的代码一步一步的执行。
比如:
r1=a;
r2=r1.x;
r3=r1.x;
编译器则可能会进行优化,将r3=r1.x这条指令替换成r3=r2,这就是指令的重排
编译器为什么要做指令的重排呢?
地球人都知道,当然是出于性能上的考虑,而指令重排能提升多少性能?
首先指令的执行可以分为这几步:
- 取指 IF
- 译码和取寄存器操作数 ID
- 执行或者有效地址计算 EX (ALU逻辑计算单元)
- 存储器访问 MEM
- 写回 WB (寄存器)
详见:https://blog.csdn.net/fuhanghang/article/details/83421254
而一段代码并不是由单条指令就可以执行完毕的,而是通过流水线来执行多条指令。
流水线技术是一种将指令分解为多步,并让不同指令的各步操作重叠,从而实现几条指令并行处理。
指令1 IF ID EX MEN WB
指令2 IF ID EX MEN WB
指令的每一步都由不同的硬件完成,假设每一步耗时1ms,执行完一条指令需耗时5ms,
每条指令都按顺序执行,那两条指令则需10ms。
但是通过流水线在指令1刚执行完IF,执行IF的硬件立马就开始执行指令2的IF,这样指令2只需要等1ms,两个指令执行完只需要6ms,效率是不是提升巨大!
先记住几个指令:
MIPS汇编指令集—https://www.cnblogs.com/yanghong-hnu/p/5635245.html
LW(加载数据到寄存器的指令)
ADD(两个定点寄存器的内容相加)
SUB(相减)
SW(把数据从寄存器存储到存储器)
现在来看一下代码 A=B+C 是怎么执行的
现有R1,R2,R3三个寄存器,
LW R1,B IF ID EX MEN WB(加载B到R1中)
LW R2,C IF ID EX MEN WB(加载C到R2中)
ADD R3,R2,R1 IF ID × EX MEN WB(R1,R2相加放到R3)
SW A,R3 IF ID x EX MEN WB(把R3 的值保存到变量A)
在ADD指令执行中有个x,表示中断、停顿,ADD为什么要在这里停顿一下呢?因为这时C还没加载到R2中,只能等待,而这个等待使得后边的所有指令都会停顿一下。
这个停顿可以避免吗?
当然是可以的,通过指令重排就可以实现,再看一下下面的例子:
要执行
A=B+C;
D=E-F;
通过将D=E-F执行的指令顺序提前,从而消除因等待加载完毕的时间。
LW Rb,B IF ID EX MEN WB
LW Rc,C IF ID EX MEN WB
LW Re,E IF ID EX MEN WB
ADD Ra,Rb,Rc IF ID EX MEN WB
LW Rf,F IF ID EX MEN WB
SW A,Ra IF ID EX MEN WB
SUB Rd,Re,Rf IF ID EX MEN WB
SW D,Rd IF ID EX MEN WB
欢迎关注作者公众号交流以及投稿
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/184068.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...