3

什么是代码分支?我在很多地方都看到过它,尤其是有点玩弄,但从来没有真正想过它?

它是如何减慢程序速度的?在编码时我应该考虑什么?

我看到提到的if陈述。我真的不明白这样的代码如何减慢代码的速度。如果条件为真,请执行以下指令,否则跳转到另一组指令?我看到另一个线程提到“分支预测”,也许这就是我真正迷路的地方。有什么可以预测的?条件就在那里,它只能是真或假。

我不认为这是这个相关问题的重复。链接的线程正在谈论参考未排序数组的“分支预测”。我在问什么是分支以及为什么需要预测。

4

4 回答 4

12

最简单的分支示例是 if 语句:

if (condition)
    doSomething();

现在 if conditionis truethendoSomething()被执行。如果不是,则执行分支,通过跳转到if.

在非常简单的机器伪代码中,这可能会被编译成以下几行:

TEST condition
JZ   label1       ; jump over the CALL if condition is 0
CALL doSomething
@@label1

分支点是JZ指令。后续执行点取决于 的测试结果condition

分支会影响性能,因为现代处理器会提前预测分支的结果并执行推测执行。如果预测结果是错误的,那么投机执行就必须解除。

如果您可以安排代码以使预测成功率更高,那么性能就会提高。这是因为推测性执行的代码现在的开销更少,因为它甚至在需要之前就已经执行了。这是可能的,因为现代处理器是高度并行的。可以使用备用执行单元来执行这种推测执行。

现在,有一种代码永远不会有分支预测未命中。那是没有分支的代码。对于无分支代码,推测执行的结果总是有用的。因此,在所有其他条件相同的情况下,没有分支的代码比有分支的代码执行得更快。

于 2013-07-24T16:05:25.927 回答
8

基本上想象工厂中的装配线。想象一下,当每个项目通过装配线时,它会到达员工 1,然后是员工 2,直到员工 5。员工 5 完成后,项目完成并准备好进行包装。因此,所有五名员工可以同时处理不同的项目,而不必互相等待。然而,与大多数装配线不同的是,员工 1 每次开始处理新项目时,它都可能是一种新类型的项目 - 而不仅仅是一遍又一遍的相同类型。

好吧,无论出于什么奇怪和富有想象力的原因,想象一下经理站在装配线的最末端。他有一个清单,上面写着:“先做这个项目。然后做那个类型的项目。然后那个类型的项目。” 等等。当他看到员工 5 完成每个项目并继续下一个项目时,经理然后告诉员工 1 开始处理哪种类型的项目,查看他们当时在列表中的位置。

现在假设该列表中有一个点-“计算机指令序列”-它说:“现在开始制作咖啡杯。如果您完成咖啡杯制作时是晚上,则开始制作冷冻晚餐。如果是白天,然后开始制作一袋咖啡渣。” 这是你的 if 语句。既然经理,在这种假的例子中,直到他真正看到完成后的杯子才真正知道一天中的什么时间,他可以等到那个时候叫下一个要制作的东西——冷冻晚餐或一些咖啡渣。

问题在于,如果像那样等到最后一秒——他必须等到才能完全确定杯子喝完的时间,以及下一个项目将是什么——然后在工人 5 完成之前,工人 1-4 根本不会做任何事情。这完全违背了流水线的目的!所以经理猜测了一下。工厂白天 7 小时营业,晚上只有 1 小时营业。因此,杯子更有可能在白天完成,从而保证咖啡渣的存在。

因此,一旦员工 2 开始制作咖啡杯,经理就会向员工 1 喊出咖啡渣。然后流水线会像以前一样继续前进,直到员工 5 用完杯子。那时经理终于知道现在是什么时间了。如果是白天,那就太好了!如果是晚上,就必须扔掉那个咖啡杯之后的一切,必须开始冷冻晚餐。...因此,从本质上讲,分支预测是经理临时冒险进行这样的猜测的地方,当他正确时,这条线移动得更快。

伪编辑:

它主要与硬件有关。主要搜索短语可能是“计算机管道 cpu”。但是指令列表已经组成——只是指令列表中有分支;它并不总是 1、2、3 等。但随着流水线的第 5 阶段正在完成指令 10,第 1 阶段可能已经在处理指令 14。通常计算机指令可以像这样分解并分段处理。如果阶段 1-n 都在同时处理某件事,并且以后没有任何东西被破坏,那比在开始另一个之前完成一个要快。

于 2013-07-24T20:18:56.367 回答
0

代码中的任何跳转都是一个分支。这发生在if语句函数调用和循环中。

现代 CPU 的流水线很长。这意味着 CPU 同时处理多条指令的各个部分。分支的问题是管道可能没有开始处理正确的指令。这意味着需要抛出推测指令,处理器需要从头开始处理指令。

当遇到分支时,CPU 会尝试预测将使用哪个分支。这称为分支预测。

大多数分支预测的优化将由您的编译器完成,因此您实际上不需要担心分支。

如果您已经分析了代码并且可以看到这是一个问题,这可能属于只担心分支优化的类别。

于 2013-07-24T16:11:07.993 回答
0

分支是与正常控制流的偏差。处理器将按顺序执行指令,但在分支中,程序计数器被移动到内存中的另一个位置(例如,取决于条件的分支或过程调用)。

于 2013-07-24T16:12:19.800 回答