生成最快的可执行文件

时间:2009-11-03 15:26:33

标签: c++ windows visual-studio-2008 optimization

我有一个非常大的程序,我在visual studio下编译(v6然后迁移到2008)。我需要可执行文件尽可能快地运行。该程序花费大部分时间处理各种大小的整数,并且IO很少。

显然我会选择最大化优化,但似乎有很多事情可以做,但不属于优化标题,这仍然会影响可执行文件的速度。例如,选择__fastcall调用约定或将结构成员对齐设置为大数。

所以我的问题是:我是否应该使用其他编译器/链接器选项来使程序更快,而不是从“属性”对话框的“优化”页面控制。

编辑:我已经广泛使用了分析器。

10 个答案:

答案 0 :(得分:12)

要考虑的另一个优化选项是优化尺寸。由于更好的缓存局部性,有时大小优化的代码比速度优化的代码运行得更快。

此外,除了优化操作之外,在分析器下运行代码并查看瓶颈所在。使用优秀的分析器所花费的时间可以在性能方面获得重大收益(特别是如果您对代码的缓存友好性提供反馈)。

最终,你可能永远都不会知道“尽可能快”。你最终需要满足于“这足以达到我们的目的”。

答案 1 :(得分:8)

Profile-guided optimization可以带来大幅加速。使用PGO构建时,我的应用程序运行速度比普通优化构建快30%。基本上,您运行一次应用程序并让Visual Studio对其进行配置,然后根据收集的数据进行优化再次构建它。

答案 2 :(得分:5)

1)使用__restrict减少别名。

2)使用__pure帮助编译器消除公共子表达式消除/死代码。

3)可以找到SSE / SIMD简介herehere。互联网并没有完全包含有关该主题的文章,但这已经足够了。对于内在函数的参考列表,您可以在MSDN中搜索“编译器内在函数”。

4)对于“宏并行化”,您可以尝试OpenMP。它是简单任务并行化的编译器标准 - 实质上,您使用少数#pragmas告诉编译器代码的某些部分是可重入的,并且编译器会自动为您创建线程。

5)我第二次认识PGO可能非常有帮助。与#3和#4不同,添加它几乎毫不费力。

答案 3 :(得分:5)

您问的是哪些编译器选项可以帮助您加速您的程序,但这里有一些常规的优化提示:

1)确保您的算法适合该作业。如果你编写一个O(shit平方)算法,那么编译器选项的数量不会对你有所帮助。

2)编译器选项没有硬性规定。有时优化速度,有时优化尺寸,并确保你计时差异!

3)了解您正在使用的平台。了解该CPU的高速缓存如何运行,并编写专门利用硬件的代码。确保你没有到处跟踪指针来访问会破坏缓存的数据。了解可用的SIMD操作并使用内在函数而不是编写汇编。如果编译器肯定没有生成正确的代码(即以错误的方式写入未缓存的内存),则只编写汇编。确保对不会使用别名的指针使用__restrict。有些平台更喜欢你通过值而不是引用来传递矢量变量,因为它们可以放在寄存器中 - 我可以继续这样做但这应该足以指出你正确的方向!

希望这有帮助,

- 汤姆

答案 4 :(得分:3)

忘记微观优化,例如你所描述的内容。通过分析器运行您的应用程序(Visual Studio中包含一个,至少在某些版本中)。分析器将告诉您应用程序花费时间的位置。

微优化很少会让您的性能提升超过几个百分点。为了获得更大的提升,您需要在代码中识别使用低效算法和/或数据结构的区域。专注于那些,例如通过改变算法。分析器将帮助识别这些问题区域。

答案 5 :(得分:2)

在依赖编译器优化之前,您应始终先解决算法问题并对其进行优化,以便在大多数情况下为您带来显着改进。

此外,你可以抛出硬件问题。您的PC可能已经拥有大部分未使用的必要硬件:GPU!提高某些类型的计算上昂贵的处理的性能的一种方法是在GPU上执行它。这是特定于硬件的,但NVIDIA提供的API恰好是:CUDA。使用GPU可能比使用CPU带来更大的改进。

答案 6 :(得分:2)

检查您正在使用的/精确模式。每个代码生成完全不同的代码,您需要根据应用程序所需的准确度进行选择。我们的代码需要精度(几何,图形代码),但我们仍然使用/ fp:fast(C / C ++ - >代码生成选项)。

另外请确保您拥有/ arch:SSE2,假设您的部署涵盖了所有支持SSE2的处理器。这将导致性能差异很大,因为编译将使用非常少的周期。博客SomeAssemblyRequired

详细介绍了详细信息

由于您已经进行了分析,因此如果没有发生,我建议循环展开。我见过VS2008没有更频繁地做这件事(模板,参考等等。)

如果适用,请在热点中使用__forceinline。

更改代码的热点以使用SSE2等,因为您的应用似乎是计算密集型。

答案 7 :(得分:1)

我同意每个人对分析的看法。但是你提到“各种尺寸的整数”。如果使用不匹配的整数进行大量算术运算,则在更改大小时会浪费很多时间,例如,在计算表达式时会短路为整数。

我还会再投入一件事。可能最重要的优化是选择和实施最佳算法。

答案 8 :(得分:1)

您有三种方法可以加快申请速度:

  1. 更好的算法 - 您没有指定算法或数据类型(是否有整数大小的上限?)或您想要的输出。

  2. 宏并行化 - 将任务拆分为块并将每个块分配给一个单独的CPU,因此,在两个核心CPU上将整数集划分为两组并为每个cpu提供一半。这取决于您使用的算法 - 并非所有算法都可以像这样处理。

  3. 微并行化 - 这与上面类似,但使用SIMD。您也可以将它与第2点结合起来。

答案 9 :(得分:0)

你说程序非常大。这告诉我它可能在层次结构中有很多类。

我对这种程序的经验是,虽然您可能认为基本结构恰到好处,并且为了获得更好的速度,您需要担心低级优化,很有可能有很多优化的机会不属于低级别

除非该程序已经进行了积极的调整,否则可能存在以中等堆栈操作形式进行大规模加速的空间,这可以通过不同方式完成。这些通常是非常无辜的,永远不会引起你的注意。它们不是“改进算法”的情况。它们通常是“良好设计”的案例,恰好处于关键路径上。

  • 不幸的是,您不能依赖分析器来查找这些内容,因为它们并非旨在寻找它们。

This is an example of what I'm talking about.