我正在开发一个项目,其中包含数千个.cpp
个文件以及数千个.h
和.hpp
,并且构建需要 28分钟从SSD运行
我们几周前从一家不同的公司继承了这个项目但是仔细阅读了makefile,他们通过.NOPARALLEL
假目标显式禁用了并行构建;我们试图找出他们是否有充分的理由。
最糟糕的情况是,加快速度的唯一方法是使用RAM驱动器。
所以我按照Tekrevue中的说明安装了Imdisk,然后使用CrystalDiskMark运行基准:
我还使用Cygwin运行dd
,与我的SSD相比,RAM驱动器的速度显着提升(至少3倍)。
但是,我的构建时间不会改变一分钟!
然后我想:也许我的专有编译器会调用一些Windows API并导致一个巨大的减速,所以我在Cygwin上从源代码构建了 fftw 。
我的预期是我的处理器使用率会增加到某个最大值并在构建期间保持不变。相反,我的用法非常尖刻:每个文件编译一个。据我所知,即使是Cygwin仍然需要与windows进行交互,所以我仍然使用尖锐的proc使用,这让我认为这不是我的编译器的问题。
确定。新理论:为每个源文件调用编译器在Windows中有一些巨大的开销,因此,我从构建日志中复制粘贴并将45个文件传递给我的编译器,并将其与分别调用编译器45次进行比较。调用ONCE的速度更快,但45个文件总共只有4秒。 我看到了与为每个文件调用一次编译器时相同的“尖峰”处理器用法。
为什么即使从RAM驱动器运行,我也无法使编译器运行得更快?什么是开销?
更新#1 我想,评论者一直在说,RAM驱动器是一种不必要的bc窗口,无论如何都会将输入和输出文件缓存在RAM中。 此外,RAM驱动器实现(即驱动程序)可能是次优的。 所以,我不再使用RAM驱动器了。
另外,有人说我应该多次运行45个文件的构建,以便消除缓存的开销:我运行了4次,每次运行 52secs 。
虚拟内存使用情况 当编译器将东西吐出到磁盘时,它实际上首先缓存在RAM中,对吧? 那么这个截图表明IO不是问题,或者说,它和我的RAM一样快。
问题: 因此,由于所有内容都在RAM中,为什么CPU%的时间更高? 我能做些什么来使单线程/作业构建更快? (请记住,这是目前的单线程构建)
更新2 下面建议我应该将我的compile-45-files调用的亲和性设置为1,这样windows就不会在调用多个核心时反弹。 结果:
所以它不是硬盘,RAM或缓存,而是CPU是瓶颈。
**谢谢你们! **为你的帮助
=============================================== =========================
我的机器:Intel i7-4710MQ @ 2.5GHz,16GB RAM
答案 0 :(得分:2)
从驱动器中读取源代码是编译软件开销的一小部分。您的CPU速度更加相关,因为解析和生成二进制文件是过程中最慢的部分。
**更新 你的图表显示了一个非常繁忙的CPU,我不确定你期望看到什么。除非构建是多线程的,并且您的内核停止调度其他密集度较低的线程,否则这肯定是繁忙处理器的图形。
答案 1 :(得分:2)
我不明白你为什么要责备操作系统,除了顺序的,哑的IO(加载源/保存中间输出 - 应该通过看到SSD和ramdisk执行相同的操作来排除)和进程启动(通过编译单个巨型文件排除)编译器和操作系统之间的交互非常少。
现在,一旦你排除了“磁盘”和处理器,我预计瓶颈就是内存速度 - 而不是RAM磁盘IO部分(可能已经被SSD大部分饱和),但是对于编译过程本身。
这实际上是一个非常常见的问题,在这个时刻,处理器通常比内存更快,这通常是瓶颈(这就是为什么目前编写缓存友好代码至关重要的原因)。处理器可能正在浪费一些重要的时间来等待从主存储器中取出缓存数据。
无论如何,这都是猜测。如果你想要一个可靠的答案,你需要像往常一样。从a list like this获取一些采样分析器,然后查看编译器浪费时间的位置。就个人而言,我希望看到一个健康的缓存未命中(如果你为ramdisk烧掉了太多内存,甚至页面错误),但任何事情都可以。
答案 2 :(得分:0)
您的跟踪显示23%的CPU使用率。你的CPU有4个实际核心(超线程使它看起来像8)。所以,你只使用一个核心到它的绝对最大值(加或减2%,这可能比你真正期望的更准确)。
由此得出的明显结论是,您的构建过程受CPU限制,因此提高磁盘速度不太可能产生太大影响。
如果你想要更快的构建,你需要弄清楚你当前的makefile有什么问题,或者写出全新的没有问题,所以你可以支持部分和并行构建。
这可以让你获得很多。基本上你做的其他任何事情(加速磁盘,超频CPU等)都会带来微不足道的好处(如果你真的很幸运,也许20%,适当的构建环境可能会给出至少20:1)大多数典型构建的改进。)