指令乱序和内存障碍(barrier)
什么是指令乱序?
指令乱序分为执行指令乱序(cpu)和编译器指令乱序。
执行指令乱序(cpu)
要了解cpu执行指令乱序,我们要先了解cpu的流水线pipeline.
cpu处理指令时,将指令的处理过程分为取指、译码、[访存]、执行、[回写]等几个阶段。
取指:顾名思义,就是到内存中(I-cache)取要执行的指令
译码:cpu识别这个指令是做什么的,比如识别出操作码[op]、操作数等
访存:cpu锁定内存的地址
执行:执行指令操作,比如ADD、sub或将内存中的数据加载到cpu寄存器中
回写:cpu将寄存器中的数据写回内存中。
如果cpu只有”一套”pipeline,那么后一条指令必须等待前一条指令执行完毕,才能执行,即使前一条指令是费时很长的IO指令(访问外设、内存等),这种方式极大的浪费了cpu资源。
为了提高CPU效率,cpu内部会有很多个“取指、译码、[访存]、执行、[回写]”器件。
所有没有显式依赖的指令可以同时取指、译码、执行而不必等待。这样大大提高了cpu的效率,提升了cpu单个指令周期内的执行指令的数目。
比如原本指令的执行顺序如下:
ldr r0, [r1]
mov r2, $3
sub r0, r2
str r0, [r1]
如果指令是按序执行的,则执行顺序如下:
图1:指令按序执行
但在现代高级的,支持多指令并发的CPU中,实际的指令执行序列可能为下面这样的:
图2:指令乱序执行