关于后端:神奇同样执行1000000次循环的时间竟然会不一样

4次阅读

共计 1830 个字符,预计需要花费 5 分钟才能阅读完成。

场景
事件是这样的,我先来还原一下场景,有如下图中的一段代码,这段代码的逻辑很简略。

学生成一个 0 -top 范畴的有序汇合,比方 top=100,那么就是生成 [0,1,2,3,…99,100];
如果 shuffle=true,则将这个汇合程序打乱,相当于洗牌;
而后遍历这个汇合,统计出汇合中数值小于 top/ 2 的数量,这个后果不论是否洗牌都是 top 的一半;
记录循环开始和完结的工夫,看看循环总共破费多少工夫。

按理说,不论这个汇合有多大,都会执行 top 次的循环,每个循环里都要执行 if 判断,所以破费的工夫不论是否洗牌应该都是一样的对吧。
然而,神奇的事件产生了!
public static void main(String[] args) {
perdication(1000000,true);
perdication(1000000,false);
}
复制代码
咱们执行这段代码,别离用有序的汇合和打乱的汇合执行,看看破费的工夫。

从执行后果发现,程序打乱的汇合执行的工夫比有序汇合执行的工夫居然要长!!并且屡次执行后,状况一样。
这是为什么呢?
原来计算机在背地帮咱们做了一些事件,对咱们的代码进行了一些性能上的优化。
计算机做的事件叫做分支预测。在开始说分支预测前,先要遍及一个概念叫做指令管道。
指令管道
当咱们编写任何计算机程序时,咱们正在编写一组咱们心愿计算机按程序执行的命令。
晚期的计算机会将这些命令一次性执行。每个命令都被加载到内存中,全副执行,只有当它实现时才会加载下一个命令。
指令管道对这种状况的一种改良技术,它容许处理器将工作分成多个局部,而后并行执行。容许解决在执行一个命令时就将一下个命令加载进来准备就绪。
比方,咱们有一个简略的程序:
int a = 0;
a += 1;
a += 2;
a += 3;
复制代码
每一行代码都会由处理器进行加载(Fetch)、解码 (Decode)、执行(Execute)、存储(Store) 等步骤执行。

从上图能够看出这四个命令的执行是如何并行运行的,从破费的工夫上变得更快。
会产生什么问题呢?
通过指令管道进行优化后,尽管能在多少状况下让程序运行变快,然而会导致呈现一些问题。
有一些命令的执行,依赖于另一些命令执行的后果,而在该命令执行时可能依赖命令还没有执行结束。
代码中的分支就可能导致这种问题产生。因为在分支局部执行方向只会抉择其中的一个,并且在执行分支之前是不能晓得走哪个方向的。
这会导致任何对分支执行方向的预测变得不平安,因为咱们无奈确定分支的具体走向。
int a = 0;
a += 1;
if (a < 10) {
a += 2;
}
a += 3;
复制代码
这段代码从执行后果上和下面的代码一样,然而因为减少了一个 if 语句,会导致计算机无法预知 if 分支的走向,所以在执行 if 之前,不能加载后续的代码命令。

能够发现,因为引入了一个 if 分支,导致执行工夫立马变长。
那这和咱们最开始的分支预测又有什么关系呢?
什么是分支预测?
其实,分支预测是对指令管道优化的一个加强。计算机会尝试预测分支的走向,而后依照预测的后果进行一些指定的加载。
int a = 0;
a += 1;
if (a < 10) {
a += 2;
}
a += 3;
复制代码
同样这段代码,计算机可能会预测 a <10 为 true,这样一来,指令执行状况将变成上面这样:

能够看到,工夫立马从原来的 11 变成 9,进步了程序性能。
然而,这样预测是存在危险的,因为计算机也可能预测谬误,如果执行后果和预测后果不统一,那么曾经加载的命令不应该被执行,将会被丢掉之后从新加载新的命令。比方,咱们将程序中的条件批改为 a >10:
int a = 0;
a += 1;
if (a > 10) {

a += 2;

}
a += 3;
复制代码
那么它的执行状况可能就是这样:

能够发现这比下面的执行工夫要慢。
分支预测有什么影响?
当初咱们晓得了分支预测,那它对代码又有什么影响呢?
通常状况下,咱们的业务逻辑并不简单,或者说因为分支预测谬误,导致多执行几个处理器的命令,对性能并不会有太大的影响。
然而在一些特定的场景下,这种机制可能就会带来微小的性能晋升。
再来回顾一下开始的代码。

就是因为在 for 循环中,对 if 条件的执行后果进行预测,并行的对指令进行加载,进步了执行效率。
而洗牌之后的汇合,因为数字程序被打乱,导致分支预测的后果少数状况下和理论不统一,导致须要丢掉命令后从新加载正确的命令执行。
小结
通过以上内容咱们理解了分支预测是什么以及它对咱们的程序产生的影响。能够让咱们进行程序性能优化时,多一个抉择。
如果你感觉本文有点意思,无妨点个赞吧。

正文完
 0