生成最快的可执行文件

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

很明显,我会select最大化优化,但似乎有很多事情可以做,而不是在优化的标题下,这仍然会影响可执行文件的速度。 例如,select__fastcall调用约定或将结构成员alignment设置为一个大数字。

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

编辑:我已经广泛使用探查器。

Solutions Collecting From Web of "生成最快的可执行文件"

1)使用__restrict减少别名。

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

3)在这里和这里可以找到SSE / SIMD的介绍。 互联网并不完全是关于这个话题的文章,但是这已经足够了。 有关内部函数的参考列表,您可以搜索MSDN中的“编译器内在函数”。

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

5)我第二interjay的意见,PGO可以是非常有帮助的。 和#3和#4不同,它几乎毫不费力地加入。

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

另外,除了优化操作之外,在分析器下运行代码并查看瓶颈在哪里。 花费在一个好的分析器上的时间可以在性能上获得重大的回报(特别是如果对代码的缓存友好性给出反馈的话)。

最终,你可能永远不知道“尽可能快”是什么。 你最终需要解决“这对我们来说足够快”。

配置文件引导的优化可能会导致较大的加速。 我的应用程序运行PGO比正常优化版本快大约30%。 基本上,您只需运行一次应用程序,然后让Visual Studio对其进行配置,然后再基于收集的数据进行优化。

你问哪个编译器选项可以帮助你加快你的程序,但是这里有一些一般的优化技巧:

1)确保你的算法适合这项工作。 如果你写一个O(shit squared)算法,那么编译器选项的大量操作将会帮助你。

2)编译器选项没有硬性规定。 有时优化速度,有时优化大小,并确保你的时间差异!

3)了解你正在从事的平台。 了解该CPU的高速缓存如何工作,编写专门利用硬件的代码。 确保你没有在任何地方跟踪指针,以获取访问会颠簸缓存的数据。 了解可用的SIMD操作,并使用内部函数而不是写入程序集。 如果编译器肯定没有生成正确的代码(例如,以不好的方式写入未缓存的内存),则只编写程序集。 确保在不会别名的指针上使用__restrict。 有些平台更喜欢你通过值传递向量变量,而不是通过引用,因为他们可以坐在寄存器 – 我可以继续这个,但这应该足以指引你在正确的方向!

希望这可以帮助,

-Tom

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

微型优化很少会给你带来超过几个百分点的性能提升。 要获得巨大的提升,您需要确定代码中使用低效算法和/或数据结构的区域。 关注这些,例如通过更改算法。 分析器将帮助识别这些问题区域。

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

还要确保你有/ arch:SSE2,假设你的部署覆盖了所有支持SSE2的处理器。 这会导致性能差异很大,因为编译将使用很少的周期。 细节在SomeAssemblyRequired博客中很好地覆盖

既然你已经分析,我会建议循环展开,如果没有发生。 我已经看到VS2008不更频繁(模板,参考等)。

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

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

在依赖编译器优化之前,您应该始终使用算法并进行优化,以在大多数情况下获得显着的改进。

你也可以在这个问题上抛出硬件。 你的电脑可能已经有了必要的硬件:GPU! 一种改进某些类型的计算昂贵处理的性能的方法是在GPU上执行它。 这是硬件特定的,但NVIDIA提供了一个完全相同的API: CUDA 。 使用GPU可能会比使用CPU有更大的改进。

我同意大家所说的关于分析。 不过你提到“各种大小的整数”。 如果你使用不匹配的整数进行大量的算术运算,那么当计算表达式时,很多时候可能会浪费在改变大小,缩短整数。

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

你有三种方法来加速你的应用程序:

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

  2. 宏并行化 – 将任务分成块,并将每个块分配给一个单独的CPU,因此,在一个双核CPU上,将整数集分成两组,每个CPU分配一半。 这取决于你正在使用的算法 – 并不是所有的算法都可以像这样处理。

  3. 微并行 – 这就像上面的,但使用SIMD。 您也可以将它与第2点相结合。

你说这个节目非常大。 这告诉我可能在层次结构中有许多类。

我对这样的程序的经验是,虽然你可能假设基本结构是正确的,为了获得更好的速度,你需要担心低级优化, 机会是非常好的,有很大的优化机会那不是低级的那种

除非该计划已经被大力调整,否则可能会有不同程度的中间堆栈操作形式大规模加速的空间。 这些通常是非常无辜的,并且永远不会引起你的注意。 他们不是“改进算法”的情况。 他们通常是恰好处于关键路径上的“良好设计”的例子。

  • 不幸的是,你不能依靠配置文件找到这些东西,因为它们不是为了寻找它们而设计的。

这是我正在谈论的一个例子。