调试版本的编译速度比发布版本慢得多

Posted

技术标签:

【中文标题】调试版本的编译速度比发布版本慢得多【英文标题】:Debug builds compile much more slowly than release 【发布时间】:2012-05-18 10:59:31 【问题描述】:

在 Visual Studio 2005 下,我们有一个包含 195 个 cpp 文件的库,构建发布大约需要 2 分钟,而构建调试大约需要 6 分钟。

我一直认为发布版本应该需要更长的时间,因为优化。为什么调试版本会比发布时间长这么多?有没有办法让我们的调试构建与发布一样快?

我们确实有大量的 boost/stl 代码。

【问题讨论】:

你是否在两者中都使用了预编译的头文件? 两者都有 PCH。 /I /D PCH 之外的构建选项是:/Od /Gm /EHsc /RTC1 /MDd /W4 /nologo /c /Wp64 /ZI /TP /errorReport:prompt /wd4018 /Zm200。是的,我想知道我们是否在那里“写了一些大的可选文件”。时间只是建立图书馆所以没有链接。 【参考方案1】:

最佳猜测:调试版本受 I/O 限制,而发布版本受处理器限制(在这种情况下)。

我们已经对我们的构建系统进行了广泛的基准测试——许多大型项目,一些小型项目。 DEBUG 构建写出大量的*.pdb 信息,更大的*.obj 文件(用于额外的调试信息)等。结果是大量更多的磁盘活动。如果您的源代码中有很多“文字”(表格、符号、字符串文字)等,这一点会更加突出。

相比之下,RELEASE 构建写出 很多 个更小的 *.obj 文件,并且不会费心编写“调试”数据库(如果您使用典型开关编译 RELEASE)。但是,RELEASE 构建中的链接器必须进行优化和其他更多的工作,而这些工作在DEBUG 中没有完成,因此它受处理器限制。如果您使用最具挑战性的链接器开关“编译到最大化速度/大小”,这将进一步对 RELEASE 造成时间惩罚。

(但是,是的,RELEASE 构建仍然必须 I/O 更新磁盘上构建的可执行文件中的地址,但是由于在RELEASE 构建中可执行文件要小得多,你的页面少了很多,所以RELEASE build 中的 I/O 损失没有DEBUG build 那么多。)

您观察到 3 倍的“RELEASEDEBUG 贵”。这对于一些 I/O 绑定的项目来说是正确的,这些项目有很多模板、许多符号和文字等。检查你的驱动器——它们是否已满,或者只是“慢速驱动器”,和/或有一些坏扇区?对于DEBUG 构建,这些会使情况变得更糟(更慢)。

是的,其他构建应该是相反的,“RELEASEDEBUG 贵 3 倍”。这些构建是处理器/链接器绑定的,而不是 I/O 绑定的。

[更新],我在问题评论中看到这是针对“静态库,无链接”的。对于 I/O 的时间惩罚(大量磁盘活动,没有链接),并且没有处理器惩罚(因为没有进行优化),这几乎是最坏的情况。所以,如果你有一个 3 倍的“DEBUG-is-slower-than-RELEASE”,这可能是它所能得到的最糟糕的(对于这个项目),这不是非典型的。添加链接选项时,RELEASE 会变慢。

【讨论】:

由于文件系统缓存的延迟回写,在 Windows 中写入文件非常便宜。只有当机器受到严重的 RAM 限制时,这个答案才有意义。可能会发生,但生成千兆字节的对象/调试数据并不容易。 @Hans,有点同意。 Lazy-writes 有帮助,但我们发现 NTFS 与其他文件系统相比,对于几乎所有文件操作来说都非常昂贵。如果文件是通过网络资源缓存/传输的,当然,惰性写入根本没有帮助(例如,构建农场、分布式构建系统)。 Win7 比 XP/Vista 增加了更多的文件句柄惩罚/延迟怪异(由于 Win7 安全性改进),并导致我们嵌入式系统出现各种文件/端口句柄问题。 This blog post 描述了如何测量在调试和发布中写入的字节数。请注意,您必须监视 devenv.exe 和 cl.exe。结果大约有 300MB 是为发布而编写的,600MB 是为调试而编写的。我只是在 shell 中测试了复制 1GB 的东西,这大约需要 10 秒。因此,在我看来,以额外的 300MB 写入可能真的需要多花 4 分钟。除了 IO 之外,肯定还有其他需要很长时间的编译器活动。【参考方案2】:

我将把starbolin 的评论作为答案:苹果和橙子。 charley 对 I/O 受限的猜测似乎与我为调试编写的 600MB 和为发布编写的 300MB 的 Process Monitor 计算不相符。也就是说,写入额外的 300MB 需要几秒钟,而不是 4 分钟。因此,我得出结论,Debug 和 Release 版本之间可能只有一堆不同的东西。尽管优化应该比不优化花费更长的时间,但这些其他仅调试活动必须花费更多时间。很高兴看到调试和发布的确切时间细分,但很明显它们是完全不同的过程,调试只需要更长的时间,至少对于 Visual Studio 2005 和我进行基准测试的项目。

【讨论】:

以上是关于调试版本的编译速度比发布版本慢得多的主要内容,如果未能解决你的问题,请参考以下文章

Pymongo 读取速度比 mongo 客户端(robomongo)慢得多

如何调试速度慢得无法忍受的 Rails 资产预编译

CNN:验证损失的下降速度比训练损失慢得多是正常的吗?

设置 debug=false 实际上会导致渲染速度慢得多?

OpenMP atomic 比对数组的关键速度要慢得多

提高Android和iOS调试编译速度