一场流水线带来的灾难
一场流水线带来的灾难
---------------------------------------------------------
Author :tiger-john
WebSite :blog.****.net/tigerjb
Email :[email protected]
Tiger声明:本人鄙视直接复制本人文章而不加出处的个人或团体,但不排斥别人转载tiger-john的文章,只是请您注明出处。3Q
---------------------------------------------------------
流水线的设计对计算机体系结构来说是一个重要意义的设计。前人不会无缘无故的把一个毫无意义的东西引入到计算机世界。
引入流六线对计算机结构的重要性及其优点本人在次不涉及。
(想知道的话,就去问问我们伟大的google老师把)
通过哲学观点我们知道任何事物都是有两面性的。如果不在合适的时间,合适地点使用,那么它就给我们这些挨踢人士带来不小的麻烦。
下面就是三级流水线带来的一些灾难。
先大概说一些废话:
三级流水线由:预取,译码和执行三部分组成。
此篇文章针对是ARM7体系结构
一. 指令的预取和自修改代码
1.许多ARM实现了在前一条指令的指令尚未完成时,将指令从存储器中取出。这个action被称为指令的预取。
2.此处说明一点:指令的预取并不代表实际执行指令(就好比一个空头支票一样,只是一个口头承诺)被预期的指令可能得不到运行。有以下两种原因:
l 发生异常
当发生异常时,当前指令执行完毕,所有预取的指令都被丢弃,指令的执行从异常向量开始。
l 发生跳转
当发生跳转时,预取的的在分支指令后的指令将被丢弃。
3.在预期指令之前要进行转移测试,例如在执行一条分支指令,此时要判断是预期分支指令之后的指令还是转移目标地址的指令。
二.预取指令引起的困惑
1.如果在存储器中的指令在被预取之后,被执行之前发生改变。
那么计算机该怎么办呢,是继续执行以前预期的指令还是执行新的指令?
(whether first or second?
This is a serious question!)
看一个程序:
;File name :triple instructions pipelining
;Author :冀博
;Function :emulate the triple instructions pipelining
;Time :2010年1月15号
AREA TEST,CODE,READONLY
CODE32
ENTRY
START LDR R0,AddInstr (1)
STR R0,NextInstr (2)
NextInstr SUB R0,R0,#0X1 (3)
SUB R1,R1,#0X1 (4)
SUB R2,R1,R0 (5)
AddInstr ADD R1,R1,#0X1 (6)
B START (7)
END
分析指令的执行过程:
1> 从地址(1)预取指
2> 从地址(2)预取值,LDR指令进入译码阶段
3> 从地址(3)预取值,STR指令进入译码阶段,同时LDR指令进入执行阶段,执行完后将地址(6)的指令装入R0.
4> 从地址(4)处预取指,STR指令进入执行阶段,执行完后将ADD 指令存入地址(3);SUB指令被覆盖。
5> 虽然SUB指令子啊存储器中被覆盖,但是它仍处于流水线上,并进入执行阶段。
Tiger-John总结:
1>如果存储器中的指令在它被预取指之后,被执行令之前发生改变,此时,对存储器中的指令进行修改一般不能阻止已取指令的执行。
2>但是,如果存储器中的指令在它被预取指之后,被执行令之前,发生中断,那么该指令就将被丢弃而步会被执行
例如:当指令第一次执行时,在STR指令之后有可能产生一个中断,那么,已经预期的SUB指令将被丢弃。当中断处理程序返回时,位于NextInstr处的指令被再次预取,而这次则执行ADD指令。
3>如果ARM处理器或存储器系统允许保持预取指令的备份并使用这些备份而不是重新预取。那么以后执行这段代码仍将执行SUB指令。