为什么虚拟机上的更多CPU内核会降低编译时间?


17

[edit#2]如果来自VMWare的任何人都可以使用VMWare Fusion的副本来打我,我很乐意做与VirtualBox与VMWare比较的相同操作。我以某种方式怀疑VMWare虚拟机管理程序将针对超线程进行更好的调整(也请参见我的答案)

我看到一些奇怪的东西。随着我在Windows 7 x64虚拟机上增加内核数量,总体编译时间会增加而不是减少。编译通常非常适合并行处理,因为在中间部分(后依赖映射)中,您可以简单地在每个.c / .cpp / .cs /任何文件上调用一个编译器实例,以建立供链接器使用的部分对象过度。所以我以为编译实际上可以很好地扩展内核数。

但是我看到的是:

  • 8核:1.89秒
  • 4核心:1.33秒
  • 2核心:1.24秒
  • 1核心:1.15秒

这仅仅是由于特定供应商的虚拟机管理程序实现(在我的情况下为type2:virtualbox)导致的设计工件,还是在更多的VM上更普遍地使虚拟机管理程序实现更简单?有这么多因素,我似乎能够为这种行为辩护和反对-因此,如果有人比我更了解这一点,我很想读您的答案。

谢谢席德

[ 编辑:解决评论 ]

@MartinBeckett:冷编译被丢弃了。

@MonsterTruck:找不到直接编译的开源项目。太棒了,但现在不能搞定我的开发环境。

@Mr Lister,@philosodad:使用VirtualBox时有8个硬件线程,因此应该以1:1映射而不进行仿真

@Thorbjorn:我有6.5GB的虚拟机和一个较小的VS2012项目-我换入/换出垃圾页面文件的可能性很小。

@All:如果有人可以指向一个开源VS2010 / VS2012项目,那么这可能比我(专有)VS2012项目更好的社区参考。Orchard和DNN似乎需要调整环境才能在VS2012中进行编译。我真的很想看看使用VMWare Fusion的人是否也看到了这一点(针对VMWare与VirtualBox划分)

测试细节:

  • 硬件:Macbook Pro Retina
    • CPU:Core i7 @ 2.3Ghz(四核,超线程= Windows任务管理器中的8核)
    • 记忆体:16 GB
    • 磁盘:256GB SSD
  • 主机操作系统:Mac OS X 10.8
  • VM类型:VirtualBox 4.1.18(类型2虚拟机管理程序)
  • 来宾操作系统:Windows 7 x64 SP1
  • 编译器:VS2012用3个C#Azure项目编译解决方案
    • VS2012插件通过“ VSCommands”来衡量编译时间
    • 所有测试运行5次,丢弃前2次,平均后3次

9
文件I / O可能会因为执行多项任务而减慢了文件I / O的速度,并且使磁盘访问虚拟驱动器
Martin Beckett 2012年

3
我想在自己的机器上重现它。您可以将示例项目上传到某个地方吗?我怀疑虚拟机在这里玩弄花样。尝试以本机方式引导到Windows(Bootcamp),看看是否观察到相同的行为-我怀疑您会这样做。
Apoorv Khurasia

1
我们在这里编译什么?许多时间,直到达到一定规模,并行化任务的开销才得到回报。了解如何编译apache或ravendb。
怀亚特·巴内特

2
您的虚拟机中的内存可能用完了,因此它开始交换。

1
在使用Maven 3.x在i3上进行编译的Java之前,我发生了同样的事情。将其默认设置为“ 4”个线程要慢得多,比显式告诉它仅使用2个内核要慢50%。我认为这与超线程上下文切换和重叠的I / O有关。

Answers:


12

答:它不会减慢速度,但确实会随着#个CPU内核而扩展。最初问题中使用的项目“太小”(实际上是大量开发,但对于编译器来说却很小/已优化),无法获得多核的好处。似乎不必计划如何分散工作,产生多个编译器进程等,而是在如此小的规模上,最好立即进行工作。

这是基于我对问题的评论(以及我的个人好奇心)所做的新实验。我使用了一个较大的VS项目-Umbraco CMS的源代码,因为它很大,是开源的,并且可以直接加载解决方案文件并进行重建(提示:umbraco_675b272bb0a3\src\umbraco.sln在VS2010 / VS2012中加载)。

现在,我所看到的就是我所期望的,即编译规模扩大了!!好吧,从某种程度上讲,我发现:

结果表

外卖:

  • 新的VM核心导致VirtualBox进程中出现新的OS X线程
  • 编译时间按预期增加(编译足够长)
  • 在8个VM内核上,由于惩罚很大(命中率达到50%),因此可能在VirtualBox中启动内核仿真
  • 以上可能是因为OS X无法将4个超线程核心(8个硬件线程)作为8个核心提供给VirtualBox

最后一点导致我通过“活动监视器”(CPU历史记录)监视所有内核的CPU历史记录,发现的是

OS X CPU历史记录图

外卖:

  • 在一个VM核心上,活动似乎在4个HW核心之间跳跃。合理地将热量均匀分布在核心层。

  • 即使在4个虚拟内核(和27个VirtualBox OS X线程或总共约800个OS X线程)上,只有偶数硬件线程(0、2、4、6)几乎饱和,而奇数硬件线程(1、3、5、7)几乎为0%。调度程序更有可能在硬件内核而不是硬件线程上工作,因此我推测OSX 64位内核/调度程序是否未针对超线程CPU优化?还是查看8VM内核设置,也许它开始以很高的CPU使用率开始使用它们?有趣的事情正在发生……好吧,对于某些达尔文开发人员来说,这是一个单独的问题……

[edit]:我很想在VMWare Fusion中尝试相同的方法。很有可能不会那么糟糕。我想知道他们是否将其展示为商业产品...

页脚:

万一图像消失了,编译时间表是(文本,难看!)

Cores in    Avg compile      Host/OSX    Host/OSX CPU
   VM         times (sec)   Threads      consumption
    1           11.83            24        105-115%
    2           10.04            25        140-190%
    4            9.59            27        180-270%
    8           14.18            31        240-430%

我怀疑4到8之间的下降是VM没有针对HT优化的组合,而HT在任何方面都不等于两倍的内核(最多 30%的性能提升,通常少得多)。
丹尼尔·B

@DanielB:在4 => 8核的情况下,问题不仅仅在于像您建议的那样,仅增加了30%(相对于+ 100%),而是性能实际上是-50%。如果硬件线程完全“失效/无用”,而工作被转移到其他内核,则性能增量将为0。因此,我更倾向于说这是VirtualBox 2类管理程序的设计。我不知道VMWare Fusion是如何实现的
DeepSpace101,2012年

“在一个VM内核上,活动似乎在4个HW内核之间跳跃。有意义的是,在内核级别平均分配热量” –不一定,通常最好在同一内核上重新安排(用于缓存等)但是系统管理程序只是在randon或最少使用的内核中选择一个,因为它认为通用进程是在其他进程正在使用这些内核的情况下进行的。在这种情况下,调度程序优化会对您不利(但以非常小的方式)
gbjbaanb 2012年

@Sid同意,我只是指出,使用HT,如果您认为实际上是100%的改善,您将(大大)减少收益的速度比您想象的要早得多。在这种情况下,很可能是导致HD争夺的原因,因此,我较早提出了一些人工CPU基准测试的建议。
Daniel B

6

发生这种情况的唯一可能原因是,您的开销超出了您的收益。

您可能正在仿真多个内核,而不是从主机分配实际的内核,甚至进程甚至线程。在我看来,这很有可能,并且显然会给您带来负面的提速。

另一种可能性是该过程本身无法很好地并行化,甚至尝试对其进行并行化也使您的通信开销比获得的更多。


your overhead is exceeding your gains:是的,但是几乎涵盖了所有内容,却不知道是什么真正造成的:) ...我正在使用VirtualBox并拥有物理核心,因此假设映射应为1:1,无需仿真。我将搜索大型开源VS2012,以便其他人也可以参考... brb
DeepSpace101,2012年

根据此答案@Sid superuser.com/a/297727,virtualbox VM应该适当使用主机核心。但是我仍然会检查主机上发生了什么,以确保正在发生预期的行为。
philosodad 2012年

0

你不是一个人 ...

在使用Maven 3.x在i3上进行编译的Java之前,我发生了同样的事情。将其默认设置为“ 4”个线程要慢得多,比显式告诉它仅使用2个内核要慢50%。

我认为这与超线程上下文切换和重叠的I / O有关。

当您开始考虑它时,这是有道理的。您可以使用良好的系统范围分析工具来证明是什么导致结果退化。

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.