- 什么是“cpu乱序执行指令”
代码,最终会变成指令,如下:
public class Test {
static int a;
static int b;
static int c;
static int d;
static int e;
static int f;
static int g;
static int h;
public static void main(String[] args) {
// a=1 对cpu来说 :
// 就是执行一条指令(可能多条,假设一条)
a = 1; // 01
b = 2; // 02
c = 3; // 03
d = 4; // 04
e = 5; // 05
f = 6; // 06
g = 7; // 07
h = a + b; // 08
/**
* 一、假设: cpu不能乱序执行指令
* 那么从01->08八条指令,cpu只能从上往下逐条执行,
* 存在问题:c=3 -> g=7共5条指令,其实可以让别的cpu同时执行,
* 这并不影响: h = a + b;
* 二、乱序执行
* 基于第一点,cpu工程师们做了优化(具体做没做我也不知道,别人都这么说的):
* cpu1执行:
* a = 1;
* b = 2;
* h = a + b;
* cpu2执行:
* c = 3; // 03
* d = 4; // 04
* e = 5; // 05
* f = 6; // 06
* g = 7; // 07
* 因此程序性能得到了提升,此优化操作就叫指令乱序执行。
* 虽然叫乱序执行,但实际上并不是胡乱执行,而是在不影响最终结果的情况下优化指令执行过程。
*/
}
}
- 证明cpu乱序执行指令
/**
* @Auther: juwm
* @Date: 2021/3/7 12:37
* @Description: cpu乱序执行(重排序)
*/
public class Disorder {
public static int a, b, x, y;
public static void main(String[] args) throws InterruptedException {
int num = 0;
for (; ; ) {
a = 0;
b = 0;
x = 0;
y = 0;
num++;
Thread one = new Thread(() -> {
a = 1; // 这里:a = 1;
x = b;
}, "01");
Thread two = new Thread(() -> {
b = 1;
y = a; // 如果是顺序执行,那一定是: y=a=1,反之就不一定了。
}, "02");
one.start();
two.start();
one.join();
two.join();
if (x == 0 && y == 0) {
String content = "第: " + num + "次," + "x=0, y=0"; // 第: 29694次,x=0, y=0
System.out.println(content);
break;
}
/**
* 一、说明:
* 想要x=0, y=0,那么x=b, y=a必须在最前面执行,才会产生这个结果。
* 也就是必须赶在a=1, b=1这两个操作之前执行x=b, y=a,
* 否则无论怎样都不可能满足x=0, y=0。
*/
/**
* 二、为什么cpu要设计为乱序执行指令
* 因为指令乱序执行,能充分利用cpu时间片(某些情况下)
* 如:某些操作要和主存交互,交互过程可能占用几十个cpu时钟周期。
* 这些时钟周期里cpu如果啥也不做,就浪费了cpu运算资源,
* 此时可以让cpu执行其它指令,从而充分利用cpu,让程序性能更好。
*/
/**
* 三、什么情况能乱序执行指令
* 乱序执行指令的目标是:充分利用cpu运算资源,提高程序性能。
* 但其前提条件是必须满足as-if-serial语义:
* 不管指令如何乱序执行(重排序),其执行结果必须和单线程执行结果一致,
* 编译器、runtime和处理器都必须遵守as-if-serial语义。
*/
}
}
}
- 参考博客
Java并发编程之happens-before和as-if-serial语义:
https://blog.csdn.net/byhook/article/details/87971081
网友评论