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

7
在Visual Studio 2005下,我们有一个包含195个cpp文件的单一库,在发布版本中编译需要约2分钟,但在调试版本中需要约6分钟。我一直认为优化应该使得发布构建时间更长,那么为什么调试版本要比发布版本花费更多时间呢?是否有任何方法可以加速我们的调试版本以达到和发布版本一样的速度呢?我们确实有相当数量的boost/stl代码。

1
你在两个项目中都使用了预编译头文件吗? - Cody Gray
1
是的,两个都使用预编译头文件。除了/I /D PCH之外,构建选项还包括:/Od /Gm /EHsc /RTC1 /MDd /W4 /nologo /c /Wp64 /ZI /TP /errorReport:prompt /wd4018 /Zm200。是的,我在想我们是否需要在其中“写一些大的可选文件”。时间仅用于构建库,因此没有链接。 - Philip
2个回答

9
最佳猜测:Debug版本受I/O限制,而Release版本受处理器限制(在这种情况下)。
我们对我们的构建系统进行了广泛的基准测试--许多大型项目,一些小型项目。DEBUG版本会写出大量的*.pdb信息,更大的*.obj文件(用于额外的调试信息),等等。结果是硬盘活动量大大增加。如果您的源代码中有很多“字面量”(表格、符号、字符串字面量等),这种情况会进一步加重。
相比之下,Release版本会写出更小的*.obj文件,并且不会打扰“调试”数据库(如果使用典型开关编译Release)。然而,Release版本中的链接器必须进行优化和其他显著更多的工作,这些工作在Debug版本中根本没有完成,因此它受到处理器限制。如果使用最具挑战性的链接器开关编译Release,这将进一步耗费时间。
(但是,是的,Release版本仍然需要在正在构建的可执行文件上更新地址,但由于Release版本的可执行文件要小得多,所以您的页面更少,因此Release版本中的I/O惩罚不像Debug版本那么严重。)
您观察到3倍的“Release比Debug更昂贵”。对于一些模板众多、符号和字面量众多等I/O受限的项目,这是正确的。检查一下您的驱动器--它们是否已经满了,或者只是“慢驱动器”,或者有一些坏扇区?这些都会使Debug版本变得更慢。
是的,其他构建应该是反过来的,Release版本应该比Debug版本“昂贵”3倍左右。这些构建受到处理器/链接器限制,而不是I/O限制。
[更新],我在问题的评论中看到这是针对“静态库、无链接”的情况。这几乎是I/O时间惩罚最严重的情况(大量的磁盘活动,没有链接),而没有处理器时间惩罚(因为没有进行优化)。因此,如果您的Debug版本比Release版本慢3倍,那可能是最糟糕的情况之一(对于这个项目),这并不罕见。当您添加链接选项时,Release版本将变得更慢。

2
在Windows中编写文件非常便宜,这要归功于文件系统缓存的延迟写回。仅当机器严重受到RAM约束时,才会出现这种情况。这可能会发生,但生成一千兆字节的对象/调试数据并不容易。 - Hans Passant
@Hans,有点同意。懒惰写入确实有帮助,但我们发现与其他文件系统相比,NTFS在几乎所有文件操作中都非常昂贵。如果文件通过网络资源进行缓存/传输,那么懒惰写入当然就没有帮助了(例如构建农场、分布式构建系统)。Win7相对于XP/Vista增加了更多的文件句柄惩罚/延迟怪异性(由于Win7安全改进),并给我们的嵌入式系统带来了各种文件/端口句柄问题。 - charley
1
这篇博客文章描述了如何在调试和发布模式下测量写入的字节数。请注意,您必须监视devenv.exe和cl.exe。发布模式下大约写入了300MB,调试模式下写入了600MB。我只是在shell中测试了复制1GB的文件,大约需要10秒钟。因此,在我看来,写入额外的300MB不可能真的需要多4分钟。除了IO之外,肯定还有其他编译器活动需要很长时间。 - Philip

2
我将把starbolin的评论放在这里作为答案:苹果和橙子。Charley猜测的I/O受限并没有通过我的Process Monitor计算得到证实,调试版写入了600MB,发布版写入了300MB。也就是说,多写入300MB只需要几秒钟,而不是4分钟。因此,我得出结论:调试版和发布版之间可能只有一堆不同之处。虽然优化应该比没有优化花费更长时间,但是这些其他仅在调试中发生的活动必须比那更耗时。能够看到调试版和发布版所需时间的详细分解将是很好的,但至少对于我基准测试的Visual Studio 2005项目来说,它们显然是非常不同的过程,调试版只需要更长的时间。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接