事实上,现代处理器会设计为一个时钟周期完成一条执行时间最长的 CPU 指令。为什么这么做呢?可以想到指令还可以再划分成一个个更小的阶段,例如,每条指令都可以分为: 取指令 - 指令译码 - 执行指令 - 内存访问 - 数据写回 这 5 个阶段。
在不改变程序结果的前提下,这些指令的各个阶段可以通过重排序和组合来实现指令级并行,这一技术在 80’s 中叶到 90’s 中叶占据了计算架构的重要地位。
现代 CPU 支持多级指令流水线,例如支持同时执行 取指令 - 指令译码 - 执行指令 - 内存访问 - 数据写回 的处理器,就可以称之为五级指令流水线。这时 CPU 可以在一个时钟周期内,同时运行五条指令的不同阶段(相当于一条执行时间最长的复杂指令),IPC = 1,本质上,流水线技术并不能缩短单条指令的执行时间,但它变相地提高了指令地**吞吐率**。
下面代码,如果不发生指令重排,会出现三种情况
x=0; y=1
x=1;y=0
x=1;y=1
因为x=b或者y=a 总会在最后一句执行
但实际上却出现了x=0,y=0,说明发生了指令重排序
package poolv1;import lombok.SneakyThrows;import lombok.extern.slf4j.Slf4j;@Slf4jpublic class Test {public static int a = 0, b = 0;public static int x = 0, y = 0;@SneakyThrowspublic static void main(String[] args) {//计数 看第几次出现优化int count = 0;while (true) {count++;a = 0;b = 0;x = 0;y = 0;Thread t1 = new Thread(new Runnable() {@Overridepublic void run() {a = 1;x = b;}});Thread t2 = new Thread(new Runnable() {@Overridepublic void run() {b = 1;y = a;}});//都可以调度t1.start();t2.start();t1.join();t2.join();// 得到线程执行完毕以后 变量的结果。log.debug("第{}次输出结果:x ={}, y ={} ", count, x, y);if (x == 0 && y == 0) {break;}}}}
