我不能,我的生命,还记得什么我们老师说那一天,我希望你可能会知道的。

该模块是"数据结构和算法",他告诉我们沿线的东西:

if 发言是最昂贵的 [东西].[东西]寄存器 [东西].

是的,我有一个可怕的记忆和我真的真的很抱歉,但我已经google搜索了几个小时,并没有来。任何想法?

有帮助吗?

解决方案

目前最底层(在硬件),是的,如果是昂贵的。为了理解为什么,你必须了解如何管道工作。

要执行存储在东西通常称为指令指针(IP)的当前指令或程序计数器(PC);这些术语是同义的,但不同的术语与不同的架构中使用。对于大多数指令,下一条指令的PC就是当前PC加上当前指令的长度。对于大多数RISC架构,指令都为恒定的长度,所以PC可以通过恒定量递增。对于CISC体系结构,如86,指令可以是可变长度的,从而使该指令解码逻辑具有找出当前指令是多长时间找到下一个指令的位置。

有关的分支说明,但是,要被执行的下一条指令不是当前指令之后的下一个位置。分行是goto的 - 他们告诉处理器下一个指令。分支可以是有条件的或无条件的,目标位置可以是固定的或计算的。

条件与无条件很容易理解 - 如果某个条件成立的条件分支仅取(例如,一个号码是否等于另一个);如果像正常的分支后的分支没有被采用,控制进行到下一个指令。对于无条件分支,该分支始终采用。条件分支在if语句和控制测试forwhile循环显示。无条件分支在无限循环,函数调用函数返回露面,breakcontinue陈述,臭名昭著的goto语句,以及更多(这些名单还远远没有穷尽)。

在分支目标是另一个重要问题。大多数分支机构有固定的分支目标 - 他们去在代码中的特定位置被固定在编译时。这包括switch报表,各种循环,经常函数调用,等等。 已计算分支计算运行时的分支的目标。这包括abs()语句(有时),从函数返回,虚拟函数调用和函数指针调用。

那么,这一切意味着性能?当处理器看到一个分支指令出现在它的管道,它需要弄清楚如何继续填补其管道。为了弄清楚什么指令来节目流中的分支之后,它需要知道两件事情:(1)如果分支将采取和(2)的分支的目标。搞清楚了这一点被称为分支预测,这是一个具有挑战性的问题。如果处理器猜测正确,程序继续全速。相反,如果处理器猜测的错误的,它只是花了一些时间计算错误的事情。它现在已经刷新其管道,并与正确的执行路径的指令重新加载它。底线:一个大的性能命中

因此,为什么if语句是昂贵的原因是由于为转移误预测即可。这仅仅是在最低水平。如果你正在编写高层次的代码,你不需要担心这些细节都没有。你应该只关心这个,如果你正在写在C语言或汇编极其性能关键代码。如果是这样的话,写自由分支代码往往优于代码分支,即使需要一些更多的指令。有一些很酷位变换花样,你可以做计算的东西,如min()max(),并没有<=>分支。

其他提示

“贵”是一个非常相对的概念,尤其是关系到“if”语句,因为你还必须考虑到该帐户的条件的成本。这可能在任何地方从几短CPU指令给测试调用出到远程数据库的函数的结果。

我就不会担心。除非你在做嵌入式编程,你可能不应该关心的“<=>”不惜一切代价。对于大多数程序员它只是不会的曾经的在你的应用程序的性能的驱动因素。

分支机构,特别是RISC架构微处理器,是一些最昂贵的指令。这是因为在很多平台上,编译器预测其执行路径将采取最有可能,并提出未来在执行这些指令,所以他们就已经是在CPU缓存时的分支发生。如果分支走另一条路,就必须回去了主存储和获取新的指令 - 这是相当昂贵的。许多RISC体系结构中,所有指令都是除了分支一个周期(通常是2个周期)。我们不是在谈论一个主要的成本在这里,所以不用担心。此外,编译器将优化比你做的时间:)一个关于EPIC架构的真正真棒东西(安腾就是一个例子)是它缓存99%(并开始处理)从分支两侧的指令,然后丢弃设定一旦分支的结果是已知的,并不需要。这节省了在事件的典型架构的额外存储器存取,它沿着不可预测的路径的分支。

查看文章更好的性能通过了分支消除的对电池性能。另一个有趣的一个是这篇文章关于网点的选择上实时碰撞检测博客

除了已经张贴在回答这个问题的答案优秀,我想放在一个提醒,虽然“if”语句被认为是昂贵的低级别的操作,试图利用在自由分支的编程技术更高水平的环境中,如一个脚本语言或业务逻辑层(无论何种语言的),可以是可笑不合适的。

绝大多数的时间,程序应当为清楚起见第一写入和性能第二优化。有许多问题域在性能是最重要的,但一个简单的事实是,大多数开发者不深的渲染引擎或连续数周运行的高性能流体动力学模拟的核心写作使用的模块。当首要任务是为您的解决方案“只是工作”在你心中的最后一件事应该是你是否能节省条件语句在你的代码的开销。

在尽可能最低的水平 if 由(后计算所有应用特定的先决条件特别的 if):

  • 一些测试指令
  • 跳到一些地方的代码,如果试验成功,继续进行转发。

相关费用是:

  • 一个低等级的比较--通常1cpu操作中,超级便宜
  • 潜在的跳-这可能是昂贵的

振振有辞为什么要跳跃是昂贵:

  • 你可以跳到arbirary代码,生活在任何地方的存储器,如果事实证明,它不是缓存的cpu--我们有一个问题,因为我们需要访问主存储器,其速度较慢
  • 现代的Cpu做的分支predition.他们试图猜测是否将会成功或不和执行代码前在管道,以加速事。如果预测的失败所有的计算完成之前,通过管道已被无效。这也是一个昂贵的运作

因此,要总结:

  • 如果可以expesive,如果你真的,真的,私人教练的护理有关的性能。
  • 你应该关心它 如果且只有如果 你是写实时光线跟踪或生物模拟或者类似的东西。没有理由关心它在大多数的现实世界中。

if本身的慢。缓慢总是相对的我敢打赌,我的生活,你有没有感到过的if语句的“开销”。如果你打算做一个高性能的代码,你migh要避免树枝反正。是什么让branch misprediction慢是处理器从noop基于一些启发和诸如此类的东西后,预加载代码。它还将从机器代码的switch分支指令后直接执行代码停止管道,由于处理器还不知道会采取什么样的路径(在流水线处理器,多条指令交织并执行)。执行的代码可能在反向执行(如果其他分支被采用。这就是所谓的&&),或||的可以在那些地方充满,这样不会发生这种情况。

如果<=>是邪,然后<=>是恶太,和<=>,<=>太。不要担心。

也许分支杀死CPU指令预取?

现代处理器具有长的执行管线,这意味着几个指令在同一时间在不同阶段执行。他们可能不总是知道一个指令的结果时,下一个开始运行。当他们碰上一个条件跳转(如果)他们有时要等到管道是空的,才可以知道指令指针应该往哪个方向走。

我认为它是一个长货运列车。它可以携带大量的货物快速的在一条直线上,但它的角不好。

奔腾4(普雷斯科特)具有31级的著名长的管道。

更多关于维基百科

我能想象这可能是指唯一的事实是,一个if语句通常会导致一个分支。取决于处理器结构的细节,分支可以导致流水线停顿或其它不太理想的情况。

然而,这是非常特殊的情况 - 大多数现代处理器都试图尽量减少分支的负面影响分支预测能力。另一个例子是如何ARM架构(和可能其他人)能够处理条件逻辑 - 的ARM具有指令级条件执行,在没有分支如此简单的条件逻辑的结果 - 的说明只是作为NOP执行,如果条件不满足

所有这一切说 - 让担心这个东西之前,你的逻辑是正确的。不正确的代码是未优化,你可以得到。

如由许多,条件分支指出可以是现代计算机上非常缓慢。

话虽这么说,有一大堆的条件分支不if语句住,你不能总是告诉编译器会想出什么样的,并担心基本的语句需要多长时间几乎总是错误的事情。 (如果你可以告诉编译器将可靠地产生,你可能不会有很好的优化编译器。)

的CPU进行了深入的流水线化。任何分支指令(IF /对/同时/开关/等)意味着CPU并不知道要加载哪些指令和下一个运行。

在等待的CPU无论是摊位知道该怎么做,或者CPU占用猜测。在旧的CPU的情况下,或者如果猜测是错误的,你将不得不承受流水线停顿,而它进入并加载正确的指令。取决于CPU这可以是高达值得失速10-20指令。

现代CPU尝试通过执行良好的分支预测,并且通过在同一时间执行多个路径,且只保留实际一个避免这种情况。这帮助了很多,但也只能走这么远。

好运在类。

另外,如果你在现实生活中担心这个,你可能做的OS设计,实时图形,科学计算,或其他类似CPU限制。简介担心之前。

还注意到,内部的一个循环 一定是非常昂贵。

现代化的CPU假定在第一次访问一个如果声明,即"如果身"是对应采取的(或者说其他的办法:它还假定一个循环体应采取的多次)(*).在第二和进一步访问,(CPU)也许可以看到 支历史表, 和看到的条件是最后的时间(这是真的吗?是假的?).如果它是虚假的最后一次,然后推测执行将进行的"人",或超越的循环。

(*)的规则实际上是"向前支不采取,后采取的分支".在一个如果声明, 一个[向]跳跃(要点 之后如果身体)如果条件计算到假(记住:CPU不管怎么说,假定不采取一个分支/跳),但在一个循环,有可能向前分支之后的位置的循环(未采取),并一向支吁repetetion(被采取).

这也是一个原因为什么呼叫一个虚拟的功能或功能的指针的呼吁是不是更糟,因为许多假设(http://phresnel.org/blog/)

写你的程序最清晰,简单,干净,是不是很明显低效的方法。这使得最昂贵的资源物尽其用,你。是将其写入或更高版本的调试(需要理解)的程序。如果性能是不够的,测量的瓶颈在哪里,看看如何减轻他们。只有在极少数情况下,你将不得不这样做的时候不用担心个人(源)的说明。性能大约是选择正确的算法和数据结构在第一线,认真编程,得到一个足够快的机器。使用编译好的,你会看到一个改制现代编译器的那种代码时感到惊讶。对于性能重组代码是一种不得已措施,代码变得更加复杂(因此buggier),难以修改,并且因此全能更昂贵。

我有这个说法和我的一个朋友曾经。他用很天真圈算法,但声称他是比我(只计算圆的1/8的那种),因为矿用,如果快。最后,if语句与开方更换,不知何故,这是速度更快。也许是因为FPU已开方建?

一些CPU的(如X86)提供分支预测到编程电平,以避免这样的分支预测的等待时间。

一些编译器自曝(如GCC)这些作为扩展高级编程语言(如C / C ++)。

()/不可能的()在Linux内核中的宏 - 如何做他们的工作?什么是他们的利益?。

在最昂贵的ALU使用方面?它使用了CPU的寄存器来存储要被比较的值和占用时间以取得,并且每个if语句运行时间进行比较的值。

因此那优化是做一个比较和运行循环之前将结果存储为一个变量。

只是想解释你缺的词。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top