事实上,现代处理器会设计为一个时钟周期完成一条执行时间最长的 CPU 指令。为什么这么做呢?可以想到指令还可以再划分成一个个更小的阶段,例如,每条指令都可以分为: 取指令 - 指令译码 - 执行指令 - 内存访问 - 数据写回 这 5 个阶段。
    在不改变程序结果的前提下,这些指令的各个阶段可以通过重排序和组合来实现指令级并行,这一技术在 80’s 中叶到 90’s 中叶占据了计算架构的重要地位。
    image.png
    现代 CPU 支持多级指令流水线,例如支持同时执行 取指令 - 指令译码 - 执行指令 - 内存访问 - 数据写回 的处理器,就可以称之为五级指令流水线。这时 CPU 可以在一个时钟周期内,同时运行五条指令的不同阶段(相当于一条执行时间最长的复杂指令),IPC = 1,本质上,流水线技术并不能缩短单条指令的执行时间,但它变相地提高了指令地**吞吐率**。
    image.png

    下面代码,如果不发生指令重排,会出现三种情况
    x=0; y=1
    x=1;y=0
    x=1;y=1
    因为x=b或者y=a 总会在最后一句执行
    但实际上却出现了x=0,y=0,说明发生了指令重排序
    image.png

    1. package poolv1;
    2. import lombok.SneakyThrows;
    3. import lombok.extern.slf4j.Slf4j;
    4. @Slf4j
    5. public class Test {
    6. public static int a = 0, b = 0;
    7. public static int x = 0, y = 0;
    8. @SneakyThrows
    9. public static void main(String[] args) {
    10. //计数 看第几次出现优化
    11. int count = 0;
    12. while (true) {
    13. count++;
    14. a = 0;
    15. b = 0;
    16. x = 0;
    17. y = 0;
    18. Thread t1 = new Thread(new Runnable() {
    19. @Override
    20. public void run() {
    21. a = 1;
    22. x = b;
    23. }
    24. });
    25. Thread t2 = new Thread(new Runnable() {
    26. @Override
    27. public void run() {
    28. b = 1;
    29. y = a;
    30. }
    31. });
    32. //都可以调度
    33. t1.start();
    34. t2.start();
    35. t1.join();
    36. t2.join();
    37. // 得到线程执行完毕以后 变量的结果。
    38. log.debug("第{}次输出结果:x ={}, y ={} ", count, x, y);
    39. if (x == 0 && y == 0) {
    40. break;
    41. }
    42. }
    43. }
    44. }