什么是代码分支

Twi*_*fty 3 c++

什么是代码分支?我已经在不同的地方看到过它,特别是有点笨拙,但从来没有真正考虑过它?

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

我看到提到的if陈述.我真的不明白这些代码如何减慢代码速度.如果条件为真,请按照说明操作,否则跳转到另一组指令?我看到另一个提到"分支预测"的帖子,也许这就是我真正迷失的地方.有什么可以预测的?条件就在那里,它只能是真或假.

我不认为这是这个相关问题的重复.链接的线程正在讨论关于未排序数组的"分支预测".我在问什么是分支以及为什么需要预测.

Dav*_*nan 10

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

if (condition)
    doSomething();
Run Code Online (Sandbox Code Playgroud)

现在,如果condition是,truedoSomething()执行.如果没有那么执行分支,跳转到结束后的语句if.

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

TEST condition
JZ   label1       ; jump over the CALL if condition is 0
CALL doSomething
@@label1
Run Code Online (Sandbox Code Playgroud)

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

分支会影响性能,因为现代处理器会提前预测分支的结果并执行推测性执行.如果预测结果是错误的,则必须解开推测性执行.

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

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


Pan*_*sis 6

基本上想象一下工厂的装配线.想象一下,当每个项目通过装配线时,它将转到员工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同时处理某些事情,并且之后没有任何事情被破坏,那么在开始另一阶段之前,这比完成一阶段更快.