vlambda博客
学习文章列表

人类和编译器谁编写的代码更快?你们的答案也许都是错的

人类和编译器谁编写的代码更快?你们的答案也许都是错的


作者 | Jussi

译者 | 明明如月

出品 | CSDN(CSDNnews)

 

现代的优化编译器真的很神奇。他们有成千上万的技巧让蹩脚的代码运行得非常快,比大多数人手写的速度还要快。这使得一些人声称程序优化是可以留给编译器,因为他们似乎在这方面做得更好。这通常会引起另一个极端的人的反对,他们说可以手工编写比任何编译器都快的代码,这使得编译器在性能方面没用武之地。

 

在某种程度上,这两种观点都是正确的。从另一方面来说,他们都错了。

 

为了了解如何做到这一点,让我们把这个问题分成两部分。

 

人类和编译器谁编写的代码更快?你们的答案也许都是错的

对于任何给定的程序,人类都可以编写比编译器更快的代码

 

这个问题很容易正式地证明。假设你有一个用某种编程语言 L 编写的程序,它的运行速度比任何手写版本都要快。人类可以查看程序的汇编输出,然后直接用 C语言编写一个等效的源代码版本。通常在这样做的时候,你会发现一些特定的优化,你可以添加这些优化来加快手写版本的速度。

 

即使编译器的输出被证明是最佳的(例如超优化), 仍然可以通过将输出作为内联汇编复制到自己的程序中来匹配。因此,我们已经证明,对于任何程序来说,人类总是更快。

 

人类和编译器谁编写的代码更快?你们的答案也许都是错的

人类不可能为每个程序写出比编译器更快的代码

 

让我们以 Firefox 为例。我们从前面的章节中知道,可以避开复杂的编译器优化,直接用 C 语言或等效的语言重写,从而获得更好的性能。缺点是,这可能在任务完成之前就过时了。

 

人类的生命是有限的。他们可以按键盘上的一个键,直到把它按坏。重写 Firefox 代码,让它在 C 语言下运行得比当前版本更快,并且启用所有优化。

 

即使通过某种技巧你可以做到这一点,在重写浏览器的过程中,浏览器上的要求也会改变。除非你添加此后添加的所有新功能,否则最终结果将毫无用处。

 

即使可以做到,优化编译器也会不断变得更好,因此你需要定期遍历整个代码库,并手动添加相同的优化以保持更新。所有这些事情都可以在理论上完成,但在实践中完全不可能。

 

人类和编译器谁编写的代码更快?你们的答案也许都是错的

这个问题提得不好

 

问编译器还是人类谁能编写更快的代码,有点像询问哪个更蓝,是大海还是天空。当然,你可以花上几年时间在 Twitter 上讨论这个问题,却很可能毫无进展,没啥意思。建议这么问: “根据我现有的需求、技能和资源,我应该手动优化这个特定的程序,还是把它留给编译器?”。

 

如果你这样做了,你就会发现: 默认情况下,你可以依靠编译器,仅仅手工处理通过分析运行中的应用程序发现的瓶颈,从而得到最好的效果。


人类和编译器谁编写的代码更快?你们的答案也许都是错的

PS. 未优化的 C 也很慢


有些人认为,当他们 C 语言编写代码时,它与底层程序集“非常接近” ,因此编译器优化对性能提高帮助不大。这种情况已经持续了好几年(可能是几十年)。特别是在 for 循环嵌套场景下,没有优化和打开 -O2 之间的性能差异有天壤之别。

 

当人们说他们可以用其他语言编写比编译器优化果盘的版本更快的代码时,实际上并非如此。除非他们 100% 纯手写 ASM[0],否则他们不会这么说。相反,他们说: “我可以采用任何算法实现,用不同的语法编写,当这两种算法都通过各自的优化编译器运行时,最终得到的程序运行速度更快。”

 

[0] 这种情况可能会出现,特别是对于 SIMD (单指令多数据流)代码而言。


相关链接:


http://nibblestew.blogspot.com/2020/04/do-humans-or-compilers-produce-faster.html


本文为CSDN翻译文章,转载请注明出处。



人类和编译器谁编写的代码更快?你们的答案也许都是错的

新勋章,新奖品,高流量,还有更多福利等你来拿~

更多精彩推荐


你点的每个“在看”,我都认真当成了喜欢