如何加速C ++编译

时间:2014-03-06 18:06:19

标签: c++ compiler-construction compilation qt5

你有什么技巧可以真正加速大型C ++源代码吗?

我用最后一个visual studio 2013编译器编译了QT5,这需要至少3个小时的intel四核3.2GHz,8GB内存和SSD驱动器。

如果我想在30分钟内完成此操作,我会有什么解决方案?

感谢。

8 个答案:

答案 0 :(得分:5)

转发声明和PIMPL。

example.h文件:

// no include
class UsedByExample;

class Example
{
  // ...
  UsedByExample *ptr; // forward declaration is good enough
  UsedByExample &ref; // forward declaration is good enough
};

example.cpp:

#include "used_by_example.h"

// ...
UsedByExample object;  // need #include

一个鲜为人知/未充分利用的事实是前向声明对函数返回值也足够好:

class Example;
Example f(); // forward declaration is good enough

只有调用f()并且必须对返回的Example对象进行操作的代码才需要定义Example

PIMPL的目的是根据前向声明的惯用法,将私有成员完全隐藏在外部编译单元之外。因此,这也可以减少编译时间。

所以,如果你有这个课程:

example.h文件:

#include "other_class.h"
#include "yet_another_class.h"
#include "and_yet_another_class.h"

class Example
{
  // ...
  public:
    void f();
    void g();
  private:
    OtherClass a;
    YetAnotherClass b;
    AndYetAnotherClass c;
};

你实际上可以把它变成两个类,一个是实现,另一个是接口。

example.h文件:

// no more includes
class ExampleImpl; // forward declaration

class Example
{
  // ...
  public:
    void f();
    void g();
  private:
    ExampleImpl *impl;
};

example_impl.h:

#include "other_class.h"
#include "yet_another_class.h"
#include "and_yet_another_class.h"

class ExampleImpl
{
  // ...
    void f();
    void g();
  // ...
    OtherClass a;
    YetAnotherClass b;
    AndYetAnotherClass c;
};

缺点可能包括更高的复杂性,内存管理问题以及增加的间接层。

答案 1 :(得分:4)

  • 使用快速SSD设置。甚至可以在您的系统上创建一个ram磁盘。

  • 项目 - >属性 - >配置属性 - > C / C ++ - >一般 - >多处理器编译:是(/ MP)

  • 工具 - >选项 - >项目和解决方案 - >构建并运行:并设置并行项目构建的最大数量。 (我的系统已经设置为8,可能是在第一次运行VS2013时确定的)

答案 2 :(得分:1)

  1. 减少依赖项的数量,这样如果代码的一部分发生更改,则不必重新编译其余部分。即包含特定标头的任何.cp / .cpp / .cc文件需要在更改标头时重新编译。如果可以的话,请向前宣布。

  2. 尽量避免编译。如果有不需要的模块,请将它们留下。如果您的代码很少更改,请将其放在静态库中。

  3. 请勿使用过多的模板。编译器必须生成模板的每个版本的新副本,并且模板的所有代码都在标题中,并且需要一遍又一遍地重新读取。这本身不是问题,但它与前向声明相反,添加了依赖关系。

  4. 如果您有每个文件使用的标头,并且很少更改,请查看是否可以将它们放在预编译的标头中。预编译头只编译一次,并以特定于编译器的格式保存,快速读取,因此对于大量使用的类,可以带来极大的加速。

  5. 请注意,这仅适用于您编写的代码。对于来自第三方的代码,只有#2和#4可以提供帮助,但不会大幅提高绝对编译时间,只会减少在构建一次后需要再次分析代码的次数。

    为了让事情更快,你的选择更有限。你已经有了SSD,所以你可能不再受硬盘限制了,而且使用SSD进行交换也应该更快,因此RAM可能不是最紧迫的问题。所以你可能受CPU限制。

答案 3 :(得分:0)

有几种选择:

1:您可以制作1(或几个).cpp文件,其中包含项目中的大量cpp文件 然后,您只编译那些文件而忽略其余文件。

  

优点:

  • 在一个机器上编译速度要快得多

  • 应该已经有工具为您生成这些文件。在任何情况下,技术都非常简单,您可以构建一个简单的脚本来解析项目文件和编译单元,之后您只需要在项目中包含这些文件并忽略其余文件

  

缺点:

  • 更改一个cpp文件将触发包含该cpp文件的重建以及在编译时需要进行的微小更改

  • 您可能需要更改一些代码才能使其正常工作,它可能不会开箱即用,例如,如果您在两个不同的cpp文件中有一个具有相同名称的函数,则需要更改该代码

2:使用像incredibuild

这样的工具
  

优点:

  • 为您的项目开箱即用。安装应用程序,您已经可以编译项目

  • 即使是小的变化,编译也非常快

  

缺点:

  • 不是免费的

  • 您将需要更多计算机才能实现speadup

您可能会找到选项2的替代方案,here是一个相关问题。 其他提高编译时间的技巧是在cpp文件中移动尽可能多的代码并避免内联声明。元编程的广泛使用也增加了构建时间。

答案 4 :(得分:0)

只需找到您的瓶颈,并改进您的PC部分。例如,HDD / SSD性能通常是瓶颈。

在代码方面,使用前向声明之类的东西来尽可能避免包含标题,从而进一步缩短编译时间。

答案 5 :(得分:0)

不要使用模板。真。如果您使用的每个类都是模板化的(如果所有类都是类),则只有一个翻译单元。因此,您的构建系统无法将编译减少到只有实际需要重建的少数部分。

如果你有大量的模板化类,但是有大量未模板化的类,情况就不会好多了:在多个编译单元中使用的任何模板化类都必须多次编译!

当然,你不想抛弃那些小而有用的模板化辅助类,但是对于你编写的所有代码,你应该在创建模板之前三思而后行。特别是,您应该避免对使用五个不同模板类的复杂类使用模板。您的代码实际上可以从中获得更多可读性。

如果你想激进,请用C语写。唯一比编译更快的是汇编程序(感谢提醒我@black)。

答案 6 :(得分:0)

除了之前所说的,你应该避免这样的事情:
 动态绑定它越复杂,编译器就越需要做的工作  2.高级优化:使用优化代码(O x)对特定体系结构进行编译需要更长时间。

答案 7 :(得分:0)

感谢您的所有答案。

我必须启用多核编译并在任何地方进行一些优化。

大部分时间成本都是因为模板。

感谢。