基本操作cpu时间成本

时间:2009-08-18 20:03:00

标签: optimization

我想知道如何针对资源非常有限的系统优化循环。比方说,如果我们有一个基本的for循环,就像(用javascript编写):


for(var i = someArr.length - 1; i > -1; i--) { someArr[i] }


老实说,我不知道,!=不比>便宜吗?

我将非常感谢任何涵盖基本运算符背景下的计算成本的资源,例如前面提到的>>~!等。

6 个答案:

答案 0 :(得分:16)

现代CPU的性能远非微不足道。以下是一些使其复杂化的事情:

  • 电脑很快。您的CPU每秒可执行超过60亿条指令。因此,即使是最慢的指令也可以每秒执行数百万次,这意味着如果你经常重要
  • 现代CPU同时有数百条指令在飞行中。它们是流水线的,这意味着在读取一条指令时,另一条指令从寄存器读取,第三条指令正在执行,第四条指令正在写入寄存器。现代CPU有15-20个这样的阶段。除此之外,他们可以在每个阶段同时执行3-4条指令。他们可以重新排序这些说明。如果乘法单元正被另一条指令使用,那么我们也许可以找到一个例如执行的加法指令。因此,即使您混入了一些缓慢的指令,通过在等待慢速指令完成时执行其他指令,可以在大多数时间内隐藏其成本。
  • 内存比CPU慢几百倍。如果通过从内存中检索数据使其成本相形见绌,那么正在执行的指令并不重要。甚至这也不可靠,因为CPU有自己的板载缓存来试图隐藏这个成本。

所以简短的回答是“不要试图超越编译器”。如果您能够在两个等效表达式之间进行选择,则编译器可能会执行相同的操作,并将选择最有效的表达式。根据所有上述因素,指令的成本会有所不同。执行哪些其他指令,CPU缓存中有哪些数据,运行代码的精确CPU模型等等。在一种情况下超高效的代码在其他情况下可能效率非常低。编译器将尝试选择最普遍有效的指令,并尽可能安排它们。除非你比编译器了解更多,否则你不太可能做得更好。

除非你真的知道你在做什么,否则不要尝试这样的微观优化。如上所示,低级性能是一个非常复杂的主题,并且很容易编写导致远较慢的代码的“优化”。或者只是牺牲对可以完全没有区别的东西的可读性。

此外,您的大多数代码根本不会对性能产生可衡量的影响。 人们通常喜欢在这个问题上引用(或错误引用)Knuth:

  

我们应该忘记小的效率,比如大约97%的时间:过早的优化是所有邪恶的根源

人们经常将此解释为“不要试图优化代码”。如果你真的阅读了完整的引用,一些更有趣的后果应该变得清晰:

大部分时间,我们应该忘记微优化。大多数代码执行得很少,优化无关紧要。记住CPU每秒可以执行的指令数量,显然必须执行非常的代码块,以便对其进行优化以产生任何影响。因此,大约97%的时间,您的优化将浪费时间。但他也说有时(3%的时间),你的优化重要。显然,寻找那些3%有点像在大海捞针。如果您只是决定“优化代码”,那么您将浪费时间在前97%。相反,您需要首先找到实际需要优化的3%。换句话说,通过分析器运行代码,让它告诉你哪个代码占用了最多的CPU时间。然后你知道在哪里优化。然后你的优化不再为时过早。

答案 1 :(得分:10)

在极端(实时嵌入式系统?)情况下,这种微优化会对您的代码产生显着差异的可能性极小。如果担心让代码可读和可维护,那么你的时间可能会更好。

如有疑问,请先问唐纳德克努特:

http://shreevatsa.wordpress.com/2008/05/16/premature-optimization-is-the-root-of-all-evil/

或者,对于微观优化的略微不那么高的看法:

http://www.codinghorror.com/blog/archives/000185.html

答案 2 :(得分:1)

大多数比较具有相同的滑行,因为处理器只是在所有方面进行比较,然后在此之后根据此前比较产生的标志做出决定,因此比较信号根本不重要。但是一些架构试图根据你所比较的价值来加速这个过程,比如0的比较。

据我所知,按位运算是最便宜的运算,比加法和减法略快。乘法和除法运算有点贵,而且比较是沿海运营的最高点。

答案 3 :(得分:1)

这就像要求一条鱼,当我宁愿教你钓鱼时。

有很简单的方法可以了解自己需要多长时间。我最喜欢的是只复制代码10次,然后将其包装在10 ^ 8次的循环中。如果我运行它并查看我的手表,它所需的秒数就会转换为纳秒。

说不做过早优化是“不要”。如果你想要“做到”,你可以尝试一种主动的性能调整技术,如this

BTW我最喜欢的循环编码方式是:

for (i = N; --i >= 0;){...}

答案 4 :(得分:0)

过早优化可能是危险的,最好的方法是编写应用程序而不用担心,然后找到慢点并优化它们。如果你真的担心这个使用较低级别的语言。与像C这样的低级语言相比,像javascript这样的解释性语言会花费你一些处理能力。

答案 5 :(得分:0)

在这种特殊情况下,> vs =可能不是性能问题。然而,>通常是更安全的选择,因为可以防止修改代码的情况流入杂草并陷入无限循环。