CPU 流水线指令流是如何运转的
处理器不会把一条指令彻底做完才动手下一条。跟着指令流走一遍:它们重叠着穿过五个级,每一个时钟节拍就前进一格。
处理器不会把一条指令彻底做完才动手下一条。跟着指令流走一遍:它们重叠着穿过五个级,每一个时钟节拍就前进一格。
处理器要执行一长串指令。如果严格一条接一条地做,芯片的大部分时间都被浪费了,因为指令的每一步只用到硬件的一小块。
流水线通过把指令处理拆成若干级、并让不同指令同时占据不同级来解决这个问题。它像一条装配线:当一条指令正在执行时,下一条正在译码,再下一条正在取指。
因为这样每一级只做一件小事,可以做得又短又快。当各级都填满后,每个时钟周期就有一条完成,而不是每五个周期才完成一条——硬件没变,只是让各级一直忙于不同的指令。
收益并非免费:让各级保持同步需要细致处理,因为指令之间有时会互相依赖。停顿与冒险正是由此而来。
一长串指令等着被执行。按常规它们会被一条条处理,每条彻底做完才开始下一条。流水线改变了这一点。
取指级从存储器读出下一条指令。它刚把指令交出去,就立刻转向下一条。
译码级分析这条指令,判断它是什么操作、需要哪些寄存器、结果该放到哪里。与此同时,取指已经在装载下一条了。
执行级完成指令要求的算术或逻辑运算,操作数从寄存器堆读出。正是这一级真正产出一个值。
如果指令需要访问存储器,这一级负责读或写。只在寄存器上操作的指令则直接通过。
最后,结果被写回寄存器堆,这条指令到此完成。因为各级重叠,此时后面已经有好几条指令正在流水线的中途了。
它是一种把指令处理拆成多个级、让不同指令同时占据不同级的做法。CPU 不再把一条指令彻底做完才做下一条,而是让它们重叠起来。
常见的一组是取指、译码、执行、访存和写回。取指取出指令,译码弄清它的含义,执行完成运算,访存读写数据,写回保存结果。
每一级只做一件小事,因此可以短而快。当各级都填满后,每个时钟周期就能完成一条指令,而不是每五个周期——硬件没变,只是让各级一直忙于不同的指令。
停顿就是流水线中途的暂停。当下一条指令无法继续时发生——比如它需要的某个结果还没算好,或必须等待访存。停顿会削减理想的重叠效果。
冒险指重叠的指令之间发生干扰,例如一条指令需要的数据另一条还在计算。处理器用停顿、提前转发结果或调整指令顺序来应对冒险。
不是。更多级可以提高时钟频率,但每一级都会增加开销,分支预测出错时回退的代价也更大。真实设计要在这两者之间权衡深度。