(3) 控制冒险
从微观的角度,在流水线处理器中,指令是并行处理的,在当前指令正在执行时,后面的很多条指令已经完成了取指和译码等步骤。然而,在程序中会存在很多的跳转语句,如果程序的实际执行路径是要跳转到其他的地址去执行,那么流水线中已经做的这些取指和译码工作就白做了,这就是流水线的控制冒险。此时,处理器需要排空流水线,跳转到新的地址处重新进入流水线。由此可知,跳转对程序性能的损失是巨大的,流水线越深,损失越大。DSP流水线更深,我们以DSP流水线为例说明这个问题的危害性。

发生跳转时的性能损失
在上面这个DSP流水线中,指令2在第8个cycle执行时,发现要跳转到其他的地方,于是流水线后面的PG等工作就全白做了。
x86处理器使用硬件冲刷流水线来保证发生跳转时,流水线能正确执行,在DSP中,硬件不处理这些冒险,而是改由软件来处理。DSP通过增加NOP来排空流水线,在跳转语句后增加5个NOP操作来保证流水线正确。
B loop;跳转到loop地址处
NOP 5;
……
loop :MPY ;loop为地址标志

加NOP解决控制冒险
跳转指令的执行阶段修改程序指针的地址,加了5个NOP后,MPY的流水线正好可以顺利执行。
在DSP中,编译器可以将指令乱序,用有效指令代替NOP指令,这样就避免了跳转带来的性能损失。
在x86 CPU上,使用分支预测用来避免跳转带来的损失。
控制冒险,如果不加任何处理,就会导致处理器执行错误,如果简单的冲刷流水线,会导致流水线上有很多空洞,影响了效率。如果想避免这个损失,在DSP上做指令的乱序,在x86上做分支预测,能弥补性能损失。