1. 名词
Clock Cycle Time
- 主频的概念大家接触的比较多,而 CPU 的 Clock Cycle Time(时钟周期时间),等于主频的倒数,意思是 CPU 能够识别的最小时间单位,比如说 4G 主频的 CPU 的 Clock Cycle Time 就是 0.25 ns,作为对比,我们墙上挂钟的Cycle Time 是 1s
- 例如,运行一条加法指令一般需要一个时钟周期时间
CPI
- 有的指令需要更多的时钟周期时间,所以引出了 CPI (Cycles Per Instruction)指令平均时钟周期数
IPC
- IPC(Instruction Per Clock Cycle) 即 CPI 的倒数,表示每个时钟周期能够运行的指令数
CPU 执行时间
- 程序的 CPU 执行时间,即我们前面提到的 user + system 时间,可以用下面的公式来表示
程序 CPU 执行时间 = 指令数 * CPI * Clock Cycle Time
2. 指令重排序优化
事实上,现代处理器会设计为一个时钟周期完成一条执行时间最长的 CPU 指令。为什么这么做呢?可以想到指令
还可以再划分成一个个更小的阶段,例如,每条指令都可以分为: 取指令 - 指令译码 - 执行指令 - 内存访问 - 数据写回 这 5 个阶段
指令重排的前提是,重排指令不能影响结果,例如
// 可以重排的例子int a = 10; // 指令1int b = 20; // 指令2System.out.println( a + b );// 不能重排的例子int a = 10; // 指令1int b = a - 5; // 指令2
3. 高并发情况可能出现的问题
int num = 0;boolean ready = false;// 线程1 执行此方法public void actor1(I_Result r) {if(ready) {r.r1 = num + num;} else {r.r1 = 1;}}// 线程2 执行此方法public void actor2(I_Result r) {num = 2;ready = true;}
上述代码的r1最终会有几种结果呢,但是让人没想到的结果还可能会是0
这种情况下是:线程2 执行 ready = true,切换到线程1,进入 if 分支,相加为 0,再切回线程2 执行 num = 2,这就是指令重排可能会导致的情况
