先给出结论:分支预测
作者使用以前火车人力预判改变匝道的案例,说明了预测对了,会话很少的时间。处理器都会有这种预测算法
有 if 语句的时候会遇到这种情况。评论区还有大神写出了替代 if 语句的代码,但是可读性极差
public class ProcessSortedArrayWithNoSorted {
public static void main(String[] args) {
// Generate data
int arraySize = 32768;
int data[] = new int[arraySize];
Random rnd = new Random(0);
for (int c = 0; c < arraySize; ++c){
data[c] = rnd.nextInt() % 256;
}
// !!! With this, the next loop runs faster
Arrays.sort(data);
// Test
long start = System.currentTimeMillis();
long sum = 0;
for (int i = 0; i < 100000; ++i)
{ //循环十万次处理
for (int c = 0; c < arraySize; ++c)
{ // Primary loop
if (data[c] >= 128) {
sum += data[c];
}
//可以替换上面的整个 if 语句判断并且排序不排序都没有影响 ;但可读性可谓极差,但是帅
// int t = (data[c] - 128) >> 31;
// sum += ~t & data[c];
}
}
System.out.println((System.currentTimeMillis() - start) / 1000.0);
System.out.println("sum = " + sum);
}
}
我自己本机运行结果:总的来说是排序快很多
未排序:7s 左右
排序:2s+
What is Branch Prediction
假设一个火车枢纽问题:
现在为了讨论问题,假设没有长距离或无线电通信。
你是一个火车枢纽的操作员并且你听到火车来了,但是你不能确定火车会往那边走。你只能让火车停下来,问司机,要往哪里走,然后你再操作路线。
火车很重,有很大的惯性,所以启动和停止都会费时费力。
有好的方法吗?你猜测火车的方向,然后提前转向:
- 猜对,正常行驶
- 错误。火车停下,重新启动
如果你总是猜对,那么火车不会停下
如果你经常猜错,那么火车会停下,在启动
现代程序都有良好的分支预测行为,准确率能高达90%,但是对于杂乱无章的数据,预测程序毫无作用。对于上面的 if 语句,就是一个分支。如果数据杂乱,那么每次预测对的情况是50%。但是排序了,在中间点上预测50%,其他前后都是 100% 预测对(相当于火车可以一直走)。