我知道这不是一个编程问题,而是相关的。
我在公平large cross platform project上工作。在Windows上我使用VC ++ 2008.在Linux上我使用gcc。项目中有大约40k个文件。在编译和链接同一个项目时,Windows比Linux慢10到40倍。我该如何解决这个问题?
Linux上的单个更改增量构建20秒>在Windows上3分钟。为什么?我甚至可以在Linux中安装'gold'链接器并将时间缩短到7秒。
同样,git在Linux上比Windows快10到40倍。
在git的情况下,git可能不是以最佳方式使用Windows而是使用VC ++?你认为微软希望让自己的开发人员尽可能高效,而更快的编译将会有很长的路要走。也许他们正试图鼓励开发人员加入C#?
作为简单测试,找到包含许多子文件夹的文件夹并执行简单的
dir /s > c:\list.txt
在Windows上。执行两次并在第二次运行时间,以便从缓存中运行。将文件复制到Linux并执行等效的2次运行并在第二次运行时进行计时。
ls -R > /tmp/list.txt
我有2个工作站具有完全相同的规格。 HP Z600s配备12gig内存,8个内核,3.0ghz。在具有~400k文件的文件夹上,Windows需要40秒,Linux需要< 1秒。
我可以设置一个注册表设置来加速Windows吗?是什么给了什么?
一些与编译时间相关的略微相关的链接,不一定是i / o。
显然there's an issue in Windows 10 (not in Windows 7) that closing a process holds a global lock。当使用多个核进行编译并因此编译多个进程时,此问题就会出现。
The /analyse
option can adversely affect perf because it loads a web browser。 (这里不相关,但很高兴知道)
答案 0 :(得分:32)
除非硬核Windows系统黑客出现,否则你不会得到超过党派评论(我不会做)和猜测(这是我将要尝试的)。
文件系统 - 您应该在同一文件系统上尝试相同的操作(包括dir
)。我遇到了this,它根据各种参数对一些文件系统进行了基准测试。
缓存。我曾经尝试在RAM磁盘上运行Linux上的编译,并发现它比在磁盘上运行要慢,这要归功于内核处理缓存的方式。这是Linux的一个重要卖点,可能是性能如此不同的原因。
Windows上的错误依赖规范。也许Windows的铬依赖规范不如Linux正确。当您进行小的更改时,这可能会导致不必要的编译。您可以使用Windows上的相同编译器工具链来验证这一点。
答案 1 :(得分:27)
一些想法:
fsutil behavior set disable8dot3 1
fsutil behavior set mftzone 2
将最后一个数字更改为3或4,以增加12.5%的增量。运行该命令后,重新启动,然后创建文件系统。fsutil behavior set disablelastaccess 1
fsutil behavior set memoryusage 2
答案 2 :(得分:23)
NTFS每次都会保存文件访问时间。您可以尝试禁用它: “fsutil behavior set disablelastaccess 1” (重启)
答案 3 :(得分:20)
就我所知,visual c ++的问题是编译器团队优先考虑这种情况不是优先事项。 他们的解决方案是您使用他们的预编译头功能。这是Windows特定项目所做的。它不便携,但它的工作原理。
此外,在Windows上,您通常拥有病毒扫描程序,以及系统还原和搜索工具,如果他们为您监控您的buid文件夹,可能会完全破坏您的构建时间。 Windows 7资源监视器可以帮助您发现它。 如果您真的感兴趣,我有a reply here一些优化vc ++构建时间的进一步提示。
答案 4 :(得分:16)
我个人发现在linux上运行一个Windows虚拟机设法消除了Windows中大量的IO缓慢,可能是因为linux vm正在进行大量的Windows本身没有的缓存。
这样做我能够加快我正在进行的大型(250Kloc)C ++项目的编译时间,从15分钟到大约6分钟。
答案 5 :(得分:7)
如果将VC 2008解决方案设置为具有.lib输出的多个项目,则需要设置“使用库依赖项输入”;这使链接器直接链接到.obj文件而不是.lib。 (实际上它会逐渐增加链接。)
将原始计算机上的目录爬网与使用其他计算机上的相同文件爬网新创建的目录进行比较有点不公平。如果要进行等效测试,则应该在源计算机上创建另一个目录副本。 (它可能仍然很慢,但这可能是由于任何数量的东西:磁盘碎片,短文件名,后台服务等)虽然我认为dir /s
的性能问题更多地与编写输出比测量实际文件遍历性能。使用庞大的目录,我的机器上的dir /s /b > nul
速度很慢。
答案 6 :(得分:6)
我很确定它与文件系统有关。我从事Linux和Windows的跨平台项目,其中所有代码都很常见,除非绝对需要依赖于平台的代码。我们使用Mercurial,而不是git,因此git的“Linuxness”不适用。与Linux相比,从中央存储库中获取更改需要永远在Windows上,但我不得不说我们的Windows 7机器比Windows XP机器做得好很多。在VS 2008之后编译代码甚至更糟。它不仅仅是hg; CMake在Windows上的运行速度也慢得多,而且这两种工具都比其他任何工具都使用文件系统。
问题非常严重,以至于我们在Windows环境中工作的大多数开发人员都不再费心去做增量构建 - 他们发现doing a unity build instead更快。
顺便说一句,如果你想在Windows中大幅提高编译速度,我建议上面提到的统一版本。在构建系统中正确实现是很痛苦的(我在CMake中为我们的团队做过),但一旦完成,我们的持续集成服务器就会自动加速。根据构建系统吐出的二进制数量,您可以获得1到2个数量级的改进。你的旅费可能会改变。在我们的例子中,我认为它加快了Linux构建三倍,而Windows大约增加了10倍,但我们有很多共享库和可执行文件(这降低了统一构建的优势)。
答案 7 :(得分:5)
如何构建大型跨平台项目? 如果你在Linux和Windows上使用常见的makefile,如果makefile没有设计成在Windows上快速运行,那么你很容易将Windows性能降低10倍。
我刚刚使用针对Linux和Windows的通用(GNU)makefile修复了一些跨平台项目的makefile。 Make正在为配方的每一行开始sh.exe
进程,导致Windows和Linux之间的性能差异!
根据GNU make文档
.ONESHELL:
应解决此问题,但Windows make不支持此功能(目前)。因此,将配方重写为单个逻辑行(例如,通过在当前编辑行的末尾添加\或\)非常有效!
答案 8 :(得分:4)
恕我直言,这完全是关于磁盘I / O性能的。数量级表明很多操作在Windows下运行到磁盘,而它们在Linux下在内存中处理,即Linux更好地缓存。 Windows下的最佳选择是将文件移动到快速磁盘,服务器或文件系统上。考虑购买固态硬盘或将文件移动到ramdisk或快速NFS服务器。
我运行了目录遍历测试,结果非常接近报告的编译时间,这表明这与CPU处理时间或编译器/链接器算法无关。
上面建议的测量时间遍历chrome目录树:
对于测试我拉了铬源(都在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) - 所有这些都没有任何明显的改进。事实是,开箱即用的Linux比Windows使用四分之一的RAM要好50倍。
对于任何想要争辩数字错误的人 - 无论出于何种原因 - 请试一试并发布您的发现。
答案 9 :(得分:2)
尝试使用jom代替nmake
在此处获取: http://qt.gitorious.org/qt-labs/jom
事实是nmake只使用了你的一个内核,jom是使用多核处理器的nmake的克隆。
由于-j选项,GNU make开箱即用,这可能是其速度与Microsoft nmake相比的原因。
jom的工作原理是在不同的处理器/内核上并行执行不同的make命令。 尝试自己感受一下差异!
答案 10 :(得分:1)
我想在Windows上使用Gnu make和MinGW工具中的其他工具添加一个观察:即使工具甚至无法通过IP进行通信,它们似乎也可以解析主机名。我猜这是由MinGW运行时的一些初始化例程引起的。运行本地DNS代理帮助我提高了这些工具的编译速度。
在我遇到大麻烦之前,因为当我并行打开VPN连接时,构建速度下降了10倍左右。在这种情况下,所有这些DNS查找都通过VPN。
这种观察也可能适用于其他构建工具,不仅仅是基于MinGW,而且它可能在最新的MinGW版本上也有所改变。