2010-05-22 60 views
5

我听过很多关于C语言的性能的东西;铸造比正常分配慢,功能调用速度慢,二元操作比正常操作快得多,等等...C:任务的执行,二进制操作等等

我确定其中的一些东西是特定于架构的,并且编译器优化可能会使一个巨大的差异,但我希望看到一张图表来得出我应该做什么以及我应该避免编写高性能程序的一般想法。有没有这样一个图表(或一个网站,一本书,任何东西)?

+8

*“...铸造速度慢......”*铸造,在C中,是在运行时的零时间操作。它在编译时完全发生。类似地,高级语言中函数调用的速度并不比C中快; *从字面上*只是“在栈上压入返回值,将0..n参数推入堆栈,执行跳转。”你从哪里得到这些“真相”?因为我会找到另一个来源。 :-) – 2010-05-22 21:42:15

+2

铸造速度很慢?在C?它甚至不存在于运行时。 – 2010-05-22 21:42:53

+2

@ T.J。有些演员不是免费的。例如,将'char'投射到'double'。仍然非常便宜。 – 2010-05-22 21:56:07

回答

10

基本上没有。从语法层面来说,没有这样的“技巧和窍门”,因为没有确凿的保证,你所陈述的任何内容都是真实的(事实上,大部分都是错误的)。

通常,性能调整应该更多地关注算法,其次是内存局部性和缓存优化。您将拥有的最佳工具是剖析器(oprofile,valgrind,cachegrind等),然后了解机器体系结构(指令组合不理想,对齐限制,内存层次和大小)和汇编语言(捕捉小于最佳内环问题)。

如果您对Intel体系结构(以及所有Intel兼容CPU)的微优化感兴趣,请致电is a must read(PDF)。 Agner's website.

+1

+1为optmisations的顺序 - 推算法第一。即使在每个步骤中进行了微优化,一个错误的算法也不会很快。 – 2010-05-22 21:49:20

+0

这是一个很棒的网站。 – 2010-05-22 22:16:44

1

基本上所有提到的操作都非常快速。除非你每秒钟做数百万次,否则不要太担心替代品之间的最小差异。

如果您的程序运行时间过于缓慢,请对其进行配置以找出所花的时间以及优化的意义。

9

在我看来,你很困惑这一切。让我们来谈谈你拖累的一些神话。

与正常作业相比,施法速度较慢。

这真的取决于你投的东西。在不同的地址类型之间,不;铸造其实是免费那里,因为你只是对同一个值应用不同的解释。在不同宽度的数值类型之间进行投射可能会稍慢(有时在赋值时隐式完成),但仍然非常快。

函数调用很慢。

不是。他们不是免费的,但成本不够高,你应该避免他们除非你有分析数据否则说。千万不要没有很好的理由这样做证明它会有所帮助。 (据我所知,恢复尝试的优化,没有我想要的性能收益的平衡)。

二元操作比正常操作更快。

什么是“正常操作”? FWIW,另外是一个二进制操作。乘法也是如此。在现代硬件上,它们都非常快。让编译器担心这一点。更重要的是你专注于描述你正在做的事情。现在

,对于事情真正成本

  • I/O。
  • 内存分配。
  • 内存拷贝。
  • 深嵌套(或很长)的循环。

保持你的眼睛在那些;他们是软件通常变慢的地方。并且总是选择好的算法和数据结构。

+0

优秀的答案。优秀。尽管堆内存分配与I/O不在同一个类中,但甚至没有关闭。堆非常快。不像演员那么快,但速度很快 - 当然,直到你跑得低。 :-) – 2010-05-22 22:05:27

+0

@ T.J。 I/O速度最慢,通常最难实际摆脱;你通常会这么做,因为有一个很好的理由。堆分配速度要快得多,但您经常做的更多;它不是害怕,但它绝对不是免费的。 – 2010-05-22 22:16:03

+1

而一个经常不必要的昂贵的领域是字符串处理。糟糕的编码人员经常在该区域编写糟糕的代码,因为他们无法很好地处理正在进行的内存拷贝和循环。 – 2010-05-22 22:17:17

1

你在哪里听说这些东西?所有在这个领域“流行病”的神话中,这可能是我听过的最令人惊讶的一个。

C尽可能接近机器语言,仍然是机器无关的“高级”语言。

所有其他答案都是正确的。

我只会在真正的软件(不是很少的两页程序)中添加过多的泛化,过度抽象,用火箭筒杀死苍蝇,这是性能不佳的压倒性原因,尽管每个最后的程序员都会考虑他/她的解决方案“简单”。

2

曾几何时,有一本书名为Efficient C。稍后,有一本名​​为的高效C/C++编程:更小,更快,更好。最近还有一个名为Efficient C++

所有这些涵盖了很多你似乎感兴趣的事情。前两种似乎已绝版,第三种可能应该是。为了保持正确和有意义,这样的图表可能需要每月更新一次。无论如何,几乎任何你认为你沿着这样的路线开始的东西都可能是错误的,而那些正确的东西很可能很快就会变得错误。例如,你仍然经常看到如果你关心性能你应该避免浮点的建议。有一段时间,这甚至是合理的 - 但现在,一些CPU通过将整数转换为浮点数来完成整数运算,进行数学运算,然后将结果转换回整数!整个使用浮点数可以提高的速度

1

我听说在C性能很多事情......

有人给了你一些非常奇怪的想法。我特别喜欢“二元”和“正常”操作之间的区别。我以为对于一台电脑,二进制正常。有人必须向我解释这个区别。

我希望看到一张图表,以获得我应该做什么以及应该如何避免编写高性能程序的一般想法。

我向您提供以下图表。它假定你已经知道了Kernighan和Ritchie的C语言水平,这是C语言的经典教科书,也是你需要需要(尽管其他人有用)的唯一C语言书籍。

Have you read Jon Bentley's book "Programming Pearls"? --no--> read it 
      | 
      | yes 
      V 
    Have you read Peter van der Linden's book 
    "Expert C Programming: Deep C Secrets"?     --no--> read it 
      | 
      | yes 
      V 
    Have you learned how to use valgrind --tool=callgrind 
    and the kcachegrind visualizer?       --no--> learn them 
      | 
      | yes 
      V 
    Congratulations! You are now equipped to write 
    reasonably efficient C programs. 

本特利书中的大部分主题,特别是算法,都值得在其他地方更深入地探讨。但是这张图表将以无痛且有趣的方式开始