【问题标题】:How does the size of a binary influence the execution speed [closed]二进制文件的大小如何影响执行速度[关闭]
【发布时间】:2012-10-07 21:26:49
【问题描述】:

二进制文件的大小如何影响执行速度?具体来说,我说的是用 ANSI-C 编写的代码,使用 gnu 或 intel 编译器翻译成机器语言。二进制文件的目标平台是运行 Linux 操作系统的具有英特尔或 AMD 多核 CPU 的现代计算机。该代码可能使用 openMP 并行执行数值计算,二进制文件可能有几兆字节。

请注意,在任何情况下执行时间都将远大于加载代码和库所需的时间。我想到了一些非常具体的代码,用于求解大型常微分方程系统,以模拟动力学方程,对于中等规模的系统,这些方程通常受 CPU 限制,但也可能受内存限制。

我在问小二进制大小是否应该成为高效代码的设计标准,或者我是否总是可以优先考虑显式代码(最终重复可以作为函数实现的代码块)和编译器优化,例如循环展开等.

我知道分析技术以及如何将它们应用于特定问题,但我想知道可以在多大程度上做出一般性陈述。

【问题讨论】:

  • 这太宽泛了。代码大小与其速度或性能之间没有 1:1 的关系。
  • 一般来说这不是问题,除非您的可执行文件的运行时间很短,或者二进制文件太大而被分页。
  • 如果您要问的问题如此广泛,几乎可以肯定您所从事的领域并不值得考虑这种优化水平。
  • 如果您非常关心性能,为什么不使用分析器?如果大小确实是一个因素,那么分析器应该可以帮助您解决这个问题。
  • @highsciguy:当您的分析器报告包含代码的地址上的多个缓存未命中时,我想。第二个影响是,即使代码永远不会被驱逐,它占用的缓存越多,其他所有内容的可用缓存就越少。你期待什么样的概括,“如果代码小于可用缓存就好了”? ;-)

标签: c performance numerical


【解决方案1】:

CPU 有缓存。

与 CPU 速度相比,访问系统内存很慢。这就是 CPU 具有缓存(由超快内存制成)的原因。

每个级别的 CPU 缓存都有不同的大小和速度。

因此,为了获得尽可能快的速度,避免在最低级别(不幸的是,这也是最小的缓存)刷新缓存至关重要。

code 和 data 都将强制刷新缓存。所以大小在这两种情况下都很重要。

例如:Code 可能在您 jump 或 call 时生成缓存未命中。 Data 可能在您在 remote address 加载 variable 时生成缓存未命中。

还有像alignment 这样的其他问题,它可以极大地影响速度,但没有什么比 CPU 缓存未命中更昂贵(重新加载 CPU 缓存涉及 CPU 内核同步,这不是一件容易的事:它可能需要 250 个 CPU循环!)。

无需进入特定平台的细节,就可以这么说。

结论:保持简单。小就是美。

【讨论】:

  • 我不认为在可执行文件的大小和指令缓存未命中发生的频率之间存在简单的(甚至可能不是复杂的)关系。如果有,这个答案并没有提供令人信服的论据。
  • 我说的不是机器指令,而是代码。代码不仅仅是指令:你有调用、跳转等会触发缓存刷新。我会在上面的回复中添加这个。
  • @Gil:调用/跳转不一定会触发缓存刷新,跳转的目标可能已经在缓存中。特别是如果它是程序的少数“热”代码。不过,您可能会将指令缓存未命中与流水线问题混为一谈。某些跳转(尽管不是全部)即使没有错过缓存也会刷新管道。我确信在“具有英特尔或 AMD 多核 CPU 的现代计算机”上发生这种情况时有规则,我只是不知道它们:-)
  • 可以写一本关于这个主题的书来揭露每一个案例——这不会培养出更好的程序员。记住问题是什么 - 这就是我回答的问题。
【解决方案2】:

CPU 只执行代码的一部分,所以它是代码的内容,以及你在其中移动多少,决定了速度。

如果您有 10Mb 的代码,并且前 9Mb 仅在启动时执行一次,那么这 9Mb 是慢还是 90Mb 或 90kb 都没有关系。如果 CPU 将 99.99% 的时间花在一些小而紧的循环中进行一些非常有效的计算,那么它会很快,如果它必须一次又一次地运行 100,000 行代码,它可能会慢得多。

优化是要查看 CPU 将大部分时间花在哪里,并在获得答案所需的 CPU 周期数上使代码尽可能高效。有时这可能意味着在其外部添加大量额外的“准备”代码,以使主要部分的工作更容易/更快。

在某些系统中,二进制大小是主要关注点(EG 嵌入式设备),但在其他系统中,它几乎完全无关紧要。

另请参阅:http://www.codeproject.com/Articles/6154/Writing-Efficient-C-and-C-Code-Optimization

【讨论】:

  • 您提到的链接提供了有害的建议。不要跟随它。
  • 想解释一下这条评论吗?
  • 是的。它解释的一些事情是完全错误的(使用小整数),其他事情是无关紧要的(关于你的编译器会比你更了解的 switch 语句的一切)或依赖于机器。几乎所有提到的都会影响代码质量,因此必须考虑过早的优化。如果您想知道如何编写快速代码,请学习了解什么是慢而不是与您的特定架构,并且不要使用文章的笼统陈述。现代架构遭受的缓存未命中和其他非常低级的东西比那里的所有东西都多。
  • 文章底部还有一条评论指出,这篇文章几乎是从 1998 年 (!) 一份关于优化 ARM 架构代码的文档中逐字复制的。大部分这些东西在你的编译器中处理得更好,剩下的问题通常源于更困难的事情(缓存未命中、错误共享等),必须在编写代码后进行诊断。
  • 对不起,@AlexandreC,我认为你的回答是错误的,他的回答是对的。如果您想提高执行速度,通常可能根本不值得您花时间优化二进制大小。我注意到没有人提供已知此技巧有效的具体示例,嗯?
猜你喜欢
  • 1970-01-01
  • 2018-02-04
  • 2014-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多