如何使Windows能够与Linux一样快地进行C ++编译?


142

我知道这不是编程问题,而是相关的。

我从事一个相当大的跨平台项目。在Windows上,我使用VC ++2008。在Linux上,我使用gcc。该项目中大约有40k个文件。Windows在编译和链接相同项目时比Linux慢10到40倍。我该如何解决?

在Linux上一次更改增量构建20秒,在Windows上一次增量构建3分钟。为什么?我什至可以在Linux中安装“ gold”链接器,并将时间缩短到7秒。

同样,在Linux上,git比Windows快10到40倍。

在git的情况下,git可能不是以最佳方式使用Windows,而是VC ++?您可能会认为Microsoft希望使自己的开发人员尽可能高效,而更快的编译将大大有助于实现这一目标。也许他们正在尝试鼓励开发人员使用C#?

作为一个简单的测试,找到一个包含很多子文件夹的文件夹,然后做一个简单的

dir /s > c:\list.txt

在Windows上。进行两次,并为第二次运行计时,以便它从缓存中运行。将文件复制到Linux并进行等效的2次运行,并安排第二次运行的时间。

ls -R > /tmp/list.txt

我有2个具有完全相同规格的工作站。配备12千兆RAM,8核3.0 GHz的HP Z600s。在包含约40万个文件的文件夹中,Windows需要40秒,而Linux需要不到1秒。

我可以设置注册表设置来加快Windows速度吗?是什么赋予了?


一些与编译时间相关的稍微相关的链接,不一定是I / O。


5
我不知道为什么,但是这是Windows和Linux在性能方面的一个已知差异,在处理单个目录中的文件负载方面,Linux比Windows更好,也许仅仅是NTFS与ext4 /等等。也可能是Windows上的Linux的dentry缓存不那么出色。
Spudd86

73
为什么关闭了?“不是建设性的”?我发现它与开发人员非常相关。
Nils,

3
这个问题的确包含事实,并且可以由任何数量的事实,参考文献或其他任何东西支持。仅仅以为标题似乎引起争议就不应阻止我们讨论一个长期存在但尚未充分讨论的问题。我自己是Windows的长期用户,所以我想问这个问题,并希望能在任何时候得到一些有成效的答案。请重新打开问题,除非您可以提供实际证据证明该问题本质上是辩论性的,没有事实依据。否则,您只是作为主持人机器人。
HalilÖzgür

2
@HalilÖzgür:好的,您的评论促使我查看修订历史记录-原始问题标题就是这样的问题。这很可能已的原因(我没有投票接近),则因为在一个帖子中有人通过原题显然冒犯,并开始肆虐,然后删除了,导致这个问题的关闭。此后,标题已被编辑,所以我认为我们很高兴。重新打开。请记住,您仍然应该尝试不讨论问题...由于OP正在寻找答案,请提供答案,仅此而已。
BoltClock

2
如果问题仍然是技术性的并且提供足够清晰的数据/事实来重现问题,那么看到@ raymond-chen chime之类的见解真是太棒了。
本杰明·波兹尊2011年

Answers:


32

除非有Windows系统的顽固黑客,否则您将不会获得党派评论(我不会这样做)和猜测(这是我将要尝试的)。

  1. 文件系统-您应尝试相同的操作(包括 dir)。我碰到了这一点,它针对各种参数对一些文件系统进行了基准测试。

  2. 正在缓存。我曾经尝试在RAM磁盘上的Linux上运行编译,但发现由于内核处理缓存的原因,编译速度比在磁盘上运行慢。这是Linux的可靠卖点,可能是性能如此不同的原因。

  3. Windows上的依赖项规范不正确。也许Windows的铬依赖规范不如Linux正确。进行小的更改时,可能会导致不必要的编译。您也许可以在Windows上使用相同的编译器工具链对此进行验证。


您能详细说明一下#2吗?这非常令人惊讶-是因为内核没有在RAM磁盘上缓存数据吗?
user541686 2011年

2
如果您将一块内存分配为虚拟磁盘,则内核无法将其用于缓存或用于其他任何用途。实际上,您正在绞尽脑汁,并强迫它为自己的算法使用更少的内存。我的知识是经验性的。使用RAMdisk进行编译时,我失去了性能。
Noufal Ibrahim 2011年

1
“除非[某个特定主题的专家]出现,否则您得到的不仅仅是党派评论和猜测”:与其他任何问题有何不同?
Dolph

1
这要归功于Win vs. Lin主题,这更像是一个迷迷。而且,与直接询问命令或使用方法的直接问题不同,该问题相当细微。
Noufal Ibrahim 2012年

#1中的链接不再有效。
alkasm

28

一些想法:

  1. 禁用8.3名称。对于具有大量文件和相对较少文件夹的驱动器,这可能是一个很大的因素:fsutil behavior set disable8dot3 1
  2. 使用更多文件夹。以我的经验,NTFS开始减速,每个文件夹约有1000个文件。
  3. 使用MSBuild启用并行构建;只需添加“ / m”开关,它将自动为每个CPU内核启动一份MSBuild。
  4. 将文件放在SSD上-极大地帮助进行随机I / O。
  5. 如果您的平均文件大小远远大于4KB,请考虑使用更大的群集大小重建文件系统,该大小大约与您的平均文件大小相对应。
  6. 确保已对文件进行碎片整理。碎片文件会导致大量磁盘寻道,这可能使您的吞吐量损失40倍以上。使用sysinternals的“ contig”实用程序或内置的Windows碎片整理程序。
  7. 如果平均文件大小较小,并且您所在的分区相对较满,则可能是由于碎片化的MFT而运行,这会降低性能。同样,小于1K的文件直接存储在MFT中。上面提到的“ contig”实用程序可以提供帮助,或者您可能需要增加MFT大小。下面的命令会将其加倍,达到音量的25%:fsutil behavior set mftzone 2将最后一个数字更改为3或4,以使大小额外增加12.5%。运行命令后,重新引导,然后创建文件系统。
  8. 禁用上次访问时间: fsutil behavior set disablelastaccess 1
  9. 禁用索引服务
  10. 禁用防病毒和反间谍软件,或者至少将相关文件夹设置为忽略。
  11. 将文件与操作系统和页面文件放在不同的物理驱动器上。使用单独的物理驱动器,Windows可以对两个驱动器使用并行I / O。
  12. 看一下您的编译器标志。Windows C ++编译器有很多选项。确保只使用您真正需要的那些。
  13. 尝试增加操作系统用于页面缓冲池的内存量(确保首先有足够的RAM): fsutil behavior set memoryusage 2
  14. 检查Windows错误日志,以确保您没有遇到偶然的磁盘错误。
  15. 查看与物理磁盘相关的性能计数器,以了解磁盘的繁忙程度。高队列长度或每次传输时间长都是不好的信号。
  16. 就原始传输时间而言,前30%的磁盘分区比其余磁盘快得多。较窄的分区还有助于最大程度地减少寻道时间。
  17. 您是否在使用RAID?如果是这样,您可能需要优化RAID类型的选择(RAID-5不利于诸如写入之类的繁重写操作)
  18. 禁用不需要的任何服务
  19. 碎片整理文件夹:将所有文件复制到另一个驱动器(仅文件),删除原始文件,将所有文件夹复制到另一个驱动器(仅空文件夹),然后删除原始文件夹,对原始驱动器进行碎片整理,首先将文件夹结构复制回,然后复制文件。当Windows一次构建一个大文件夹时,这些文件夹最终会变得零散且缓慢。(“ contig”也应在此提供帮助)
  20. 如果您受I / O约束并且有CPU周期可节省,请尝试打开磁盘压缩。它可以为高度可压缩的文件(例如源代码)提供一些显着的加速,并且会花费一些CPU成本。

1
即使您做了所有这些事情,您也不会接近Linux性能。请尝试以下测试,如果您不同意,请发布时间。
b7kich 2011年

6
我们需要一个更好的基准。IMO,测量枚举文件夹所花费的时间不是很有用。NTFS通过btree结构针对单文件查找时间进行了优化。在Linux中(我上次看过),一个应用程序可以通过一个系统调用来读取整个文件夹,并以用户代码完全遍历结果结构。Windows需要为每个文件进行单独的sys调用。无论哪种方式,编译器应该不需要读取整个文件夹....
RickNZ

3
然后,您所描述的正是问题所在。选择不同的基准并不能解决问题-您只是将目光移开了。
b7kich 2011年

2
问题是关于优化编译时间。文件夹枚举时间不会在Windows上占据编译时间,即使文件夹中有成千上万个文件也是如此。
RickNZ

1
进行了上述建议的某些更改后,铬树的第二次“ ls -R”运行对我来说需要4.3秒(与OP中的40秒相比)。“ dir / s”大约需要一秒钟。切换到SSD并不能单独枚举,但我怀疑它会有助于编译。
RickNZ

25

NTFS每次都节省文件访问时间。您可以尝试禁用它:“ fsutil行为设置disablelastaccess 1”(重新启动)


6
测试从之前的36秒减少了4秒。与我的Linux VM上的.6秒相比,这仍然是令人讨厌的
b7kich 2011年

21

据我所知,Visual c ++的问题在于,编译器团队优化此方案不是优先考虑的问题。他们的解决方案是您使用他们的预编译头功能。这是Windows特定项目完成的工作。它不是便携式的,但是可以工作。

此外,在Windows上,您通常具有病毒扫描程序以及系统还原和搜索工具,如果它们为您监视buid文件夹,则它们可能会完全破坏您的构建时间。Windows 7资源监视器可以帮助您发现它。如果您真的有兴趣,我在这里有一些关于优化vc ++构建时间的其他提示的答复


17

我个人发现,在Linux上运行Windows虚拟机设法消除了Windows中的大量IO慢速情况,这可能是因为linux vm正在执行很多Windows本身没有进行的缓存。

这样,我可以将我正在处理的大型(250Kloc)C ++项目的编译时间从15分钟缩短到大约6分钟。


认真吗?您的意思是我应该试用使用VM作为开发人员吗?听起来很奇怪...您使用什么VM?
Martin Booka Weser 2011年

8
我在Windows 7工作站中运行的Ubuntu 11.04 VM上测试了上述方案。Linux VM为0.6秒,Windows工作站为36秒
b7kich 2011年

2
如果您使用virtualbox并设置了共享驱动器,则实际上可以免费加快编译速度。
orlp

这里的措辞非常混乱,但是我认为这意味着运行Linux的Windows托管VM,而不是Linux上的Windows运行VM ...这很有趣,但是我的第一个字面意思是,阅读此书建议在Windows中运行Windows。虚拟机托管在Linux上编译导致更快的速度比运行Windows本身-而会已经真正得到的东西。
underscore_d

@underscore_d,我见过的东西,其中一个Windows的虚拟机上运行比在真正的硬件速度更快。可能是因为Linux告诉Windows它在真实磁盘上运行,而Linux实际上在后台进行了积极的缓存。例如,在虚拟机中安装Windows的速度也非常快。这可以追溯到XP时代,但是如果今天有很大的不同,我会感到惊讶。
法肯教授,

17

这样做的困难是由于C ++倾向于在许多小的单个文件中扩展自身和进行编译。这是Linux擅长的领域,而Windows不是。如果您想为Windows创建一个真正快速的C ++编译器,请尝试将所有内容保留在RAM中并尽可能少地触摸文件系统。

这也是制作更快的Linux C ++编译链的方式,但是在Linux中它不那么重要,因为文件系统已经为您做了很多调整。

原因是由于Unix文化:从历史上看,文件系统性能在Unix世界中比在Windows中具有更高的优先级。并不是说它不是Windows的优先级,而是Unix中的优先级更高。

  1. 访问源代码。

    您无法更改无法控制的内容。缺乏对Windows NTFS源代码的访问权限,这意味着大多数改进性能的努力都是通过硬件改进来完成的。也就是说,如果性能变慢,则可以通过改进硬件(总线,存储介质等)来解决此问题。如果您必须解决该问题,而不能解决它,那么您只能做很多事情。

    访问Unix源代码(甚至在开放源代码之前)的访问更为广泛。因此,如果您想提高性能,则可以首先在软件(更便宜,更轻松)中解决它,然后在硬件中解决它。

    结果,世界上有很多人通过研究Unix文件系统并找到提高性能的新颖方法来获得博士学位。

  2. Unix趋向于处理许多小文件。Windows趋向于几个(或单个)大文件。

    Unix应用程序倾向于处理许多小文件。想一想软件开发环境:许多小源文件,每个都有自己的目的。最后阶段(链接)确实创建了一个大文件,但这只是一个很小的百分比。

    结果,Unix对打开和关闭文件,扫描目录等进行了高度优化的系统调用。Unix研究论文的历史跨越了数十年的文件系统优化,这些思想为改善目录访问(查找和全目录扫描),初始文件打开等等投入了很多思想。

    Windows应用程序倾向于打开一个大文件,将其长时间打开,完成后将其关闭。想想MS-Word。msword.exe(或其他任何文件)一次打开文件并追加几个小时,更新内部块,依此类推。优化文件打开的价值将浪费时间。

    Windows基准测试和优化的历史一直取决于人们读取或写入长文件的速度。那就是被优化的。

    可悲的是,软件开发已趋于第一种情况。Heck是Unix上最好的文字处理系统(TeX / LaTeX),鼓励您将每个章节放在不同的文件中并将其全部包含在一起。

  3. Unix专注于高性能。Windows专注于用户体验

    Unix在服务器机房中启动:没有用户界面。用户唯一看到的就是速度。因此,速度是重中之重。

    Windows在桌面上启动:用户只关心他们看到的内容,并且看到UI。因此,在改善UI上花费的精力多于性能。

  4. Windows生态系统取决于计划的淘汰。当只有一两年的新硬件时,为什么要优化软件?

    我不相信阴谋论,但如果我这样做,我会指出,在Windows文化中,很少有提高性能的动机。Windows商业模式取决于人们购买诸如发条之类的新机器。(这就是如果MS延迟发布操作系统或Intel错过芯片发布日期的原因,成千上万家公司的股价受到影响的原因。)这意味着可以通过告诉人们购买新硬件来解决性能问题。不是通过改善真正的问题:缓慢的操作系统。Unix来自学术界,那里的预算很紧,您可以通过发明一种使文件系统更快的新方法来获得博士学位。学术界很少有人通过发出采购订单来解决问题。

    另外,由于Unix是开放源代码的(即使不是开放源代码,每个人都可以访问源代码),任何无聊的博士生都可以阅读该代码并通过使其变得更好而出名。在Windows中不会发生这种情况(MS确实有一个程序可以使学者访问Windows源代码,但很少被利用)。查看以下与Unix相关的性能论文选集:http //www.eecs.harvard.edu/margo/papers/或查阅Osterhaus,Henry Spencer或其他人撰写的论文的历史。赫克(Heck)是Unix历史上最大的辩论之一,也是Osterhaus和Selzer之间的来回交流 : //www.eecs.harvard.edu/margo/papers/ http://www.eecs.harvard.edu/margo/papers/usenix95-lfs/supplement/rebuttal。 html 您不会在Windows世界中看到这种情况。您可能会看到供应商互相竞争,但这在最近似乎很少见,因为创新似乎都在标准机构层面。

我就是这样看的。

更新: 如果您查看来自Microsoft的新编译器链,您会非常乐观,因为它们所做的很多事情使得将整个工具链保留在RAM中并减少重复工作的工作变得更加容易。非常令人印象深刻的东西。


6
说原因是“文化的,而不是技术的”并不能真正回答问题。显然,有一个或多个潜在的技术原因,使得某些操作在Windows上比在Linux上慢。现在,文化问题可以解释为什么人们做出他们做出的技术决定;但这是一个技术问答网站。答案应涵盖一个系统比另一个系统慢的技术原因(以及可以采取哪些措施来改善这种情况),而不是无法证明的关于文化的猜想。
Brian Campbell

这似乎没有很多技术信息。大多数情况下是间接的。我想我们会得到真正的技术信息的唯一途径是通过看两个编译器之间的差异,构建系统,等等等等
surfasb

Windows应用程序倾向于打开一个大文件,并将其长时间打开 -许多UNIX应用程序都这样做。服务器,我的Emacs等
Noufal易卜拉欣

我认为emacs不管文件大小,都不会长时间打开文件。它当然不会写入文件的中间,而是像数据库那样对其进行更新。
TomOnTime

…服务器也不这样做。它们在* nix系统上的功能通常分为许多小模块,而服务器核心本质上是一个空外壳。
频谱

7

增量链接

如果将VC 2008解决方案设置为具有.lib输出的多个项目,则需要设置“使用库依赖输入”;这使得链接器直接链接到.obj文件而不是.lib。(实际上使它逐渐链接。)

目录遍历性能

将原始计算机上的目录爬网与另一台计算机上具有相同文件的新创建目录进行爬网进行比较有点不公平。如果要进行等效测试,则可能应该在源计算机上制作该目录的另一个副本。(它可能仍然很慢,但这可能是由于许多原因造成的:磁盘碎片,文件名短,后台服务等。)尽管我认为性能问题dir /s与写输出比测量实际文件更多有关。遍历性能。dir /s /b > nul在拥有巨大目录的计算机上,Even 速度很慢。


6

我很确定它与文件系统有关。我在Linux和Windows的跨平台项目中工作,除了绝对必要的平台相关代码外,所有代码都是通用的。我们使用Mercurial,而不是git,因此git的“ Linuxness”不适用。与Linux相比,Windows永远都需要从中央存储库中进行更改,但是我不得不说我们的Windows 7计算机的性能要比Windows XP计算机好得多。在那之后编译代码在VS 2008上甚至更糟。CMake在Windows上的运行速度也慢得多,并且这两个工具使用文件系统的速度比其他任何工具都要高。

这个问题是如此严重,以至于大多数在Windows环境中工作的开发人员甚至都不再烦恼进行增量构建-他们发现进行统一构建反而会更快。

顺便说一句,如果您想大大降低Windows中的编译速度,建议您使用上述统一版本。在构建系统中正确实现是很痛苦的(我是在CMake中为我们的团队完成的),但是一旦完成,将为我们的持续集成服务器自动加快速度。根据您的构建系统吐出的二进制文件的数量,您可以获得1-2个数量级的改进。你的旅费可能会改变。在我们的案例中,我认为它使Linux构建加快了三倍,而Windows构建加快了约10倍,但是我们拥有许多共享库和可执行文件(这降低了统一构建的优势)。


5

您如何构建大型跨平台项目?如果您在Linux和Windows上使用通用的makefile,则如果makefile在Windows上设计得不快,则很容易使Windows性能降低10倍。

我只是使用针对Linux和Windows的通用(GNU)生成文件修复了跨平台项目的某些生成文件。Make正在启动sh.exe配方每一行的过程,从而导致Windows和Linux之间的性能差异!

根据GNU make文档

.ONESHELL:

应该可以解决该问题,但是Windows make不(当前)支持此功能。因此,将配方重写为单个逻辑行(例如,通过在当前编辑器行的末尾添加; \或\)非常有效!


4

恕我直言,这全部与磁盘I / O性能有关。数量级表明,许多操作在Windows下会转到磁盘,而在Linux下会在内存中处理,即Linux缓存更好。Windows下最好的选择是将文件移动到快速磁盘,服务器或文件系统上。考虑购买固态驱动器或将文件移动到ramdisk或快速NFS服务器。

我运行了目录遍历测试,结果与报告的编译时间非常接近,这表明这与CPU处理时间或编译器/链接器算法完全无关。

以上建议遍历铬目录树的时间:

  • NTFS上的Windows Home Premium 7(8GB Ram):32秒
  • NTFS上的Ubuntu 11.04 Linux(2GB Ram):10秒
  • ext4上的Ubuntu 11.04 Linux(2GB Ram):0.6秒

为了进行测试,我提取了铬源(均在win / linux下)

git clone http://github.com/chromium/chromium.git 
cd chromium
git checkout remotes/origin/trunk 

衡量我跑步的时间

ls -lR > ../list.txt ; time ls -lR > ../list.txt # bash
dir -Recurse > ../list.txt ; (measure-command { dir -Recurse > ../list.txt }).TotalSeconds  #Powershell

我确实关闭了访问时间戳,病毒扫描程序并增加了Windows(> 2Gb RAM)下的缓存管理器设置-所有这些都没有任何明显的改进。事实是,具有四分之一RAM的Linux的开箱即用性能比Windows好50倍。

对于任何想证明数字错误的人(无论出于何种原因),请尝试一下并发表您的发现。


1
在进行了一些调整之后,我在Windows的答案中进行了描述,然后在铬树上运行上述“ ls -lR”测试需要19.4秒。如果我改用“ ls -UR”(不获取文件统计信息),则时间降至4.3秒。将树移动到SSD并不能加快速度,因为文件数据在第一次运行后就由OS缓存。
RickNZ

感谢分享!尽管与Windows 7的“即用型”方案相比,它的系数提高了10倍,但仍比Linux / ext4差10倍。
b7kich 2012年

我认为OP的重点是提高Windows性能,对吗?另外,正如我在上面发布的,“ dir / s”运行大约一秒钟。
RickNZ

3

尝试使用jom代替nmake

在这里获取:https : //github.com/qt-labs/jom

事实是nmake仅使用您的一个内核,jom是nmake的克隆,它利用了多核处理器。

由于-j选项,GNU开箱即用地执行该操作,这可能是其速度与Microsoft nmake相比的原因。

jom通过在不同的处理器/内核上并行执行不同的make命令来工作。尝试一下自己与众不同!


1

我只想使用Windows上的MinGW工具中的Gnu make和其他工具来添加一个观察结果:即使工具甚至无法通过IP进行通信,它们也似乎可以解析主机名。我想这是由MinGW运行时的一些初始化例程引起的。运行本地DNS代理有助于我使用这些工具提高编译速度。

在我头疼之前,因为当我并行打开VPN连接时,构建速度下降了10倍左右。在这种情况下,所有这些DNS查找都通过VPN。

此观察结果还可能适用于其他构建工具,不仅是基于MinGW的工具,同时它可能已在最新的MinGW版本上进行了更改。


0

最近,我可以使用Gnu make通过使用win-bash版本替换mingw bash.exe来归档另一种将Windows上的编译速度提高约10%的方法。

(对于交互式编辑,winbash不太舒服。)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.