克隆()/ fork()/进程创build在一些机器上是慢的

在我的一些机器上创build新的进程是非常缓慢的,而不是其他的。

这些机器都是类似的,一些较慢的机器在相同的硬件和内核(2.6.32-26,Ubuntu 10.04)上运行完全相同的工作负载,就像一些快速机器一样。 不涉及stream程创build的任务在所有机器上都是相同的速度。

例如,这个程序在受影响的机器上执行速度慢了50倍:

int main() { int i; for (i=0;i<10000;i++) { int p = fork(); if (!p) exit(0); waitpid(p); } return 0; } 

什么可能导致创build任务慢得多,我可以在机器中寻找哪些其他差异?

编辑1:运行bash脚本(因为他们产生了很多subprocess)在这些机器上也是非常慢的,对缓慢的脚本进行比较显示了clone()内核调用的速度减慢。

编辑2: vmstat在快速vs慢速机器上不显示任何显着差异。 他们都有足够的内存用于他们的工作负载,并且不去交换。

编辑3:我没有看到任何可疑的dmesg

编辑4:我不知道为什么这是在stackoverflow现在,我不是问上面的示例程序(只是用它来演示问题),但Linuxpipe理/调整,但如果人们认为它属于这里,很酷。

我们遇到了与我们的应用程序堆栈相同的问题,注意到应用程序性能的大幅降低以及strace的更长克隆时间。 在18个节点上使用你的测试程序,我把你的结果复制到了我们正在经历缓慢克隆时间的同一个3上。 所有节点都以相同的方式配置,但硬件略有不同。 我们检查了BIOS,vmstat,vm.overcommit_memory,并取代了没有改进的RAM。 然后,我们将驱动器移至更新的硬件,问题得到解决。

CentOS 5.9 2.6.18-348.1.1.el5#1 SMP星期二Jan 22 16:19:19 EST 2013 x86_64 x86_64 x86_64 GNU / Linux

“坏”和“好”lspci:

 $ diff ../bad_lspci_sort ../good_lspci_sort < Ethernet controller: Intel Corporation 82579LM Gigabit Network Connection (rev 05) > Ethernet controller: Intel Corporation 82574L Gigabit Network Connection < Host bridge: Intel Corporation Xeon E3-1200 Processor Family DRAM Controller (rev 09) > Host bridge: Intel Corporation Xeon E3-1200 v2/Ivy Bridge DRAM Controller (rev 09) < ISA bridge: Intel Corporation C204 Chipset Family LPC Controller (rev 05) > ISA bridge: Intel Corporation C202 Chipset Family LPC Controller (rev 05) < PCI bridge: Intel Corporation 6 Series/C200 Series Chipset Family PCI Express Root Port 6 (rev b5) > PCI bridge: Intel Corporation 6 Series/C200 Series Chipset Family PCI Express Root Port 7 (rev b5) < VGA compatible controller: Matrox Electronics Systems Ltd. MGA G200e [Pilot] serverEngines (SEP1) (rev 04) > VGA compatible controller: Matrox Electronics Systems Ltd. MGA G200eW WPCM450 (rev 0a) 

我可能会开始使用strace来查看正在运行的系统调用以及哪些系统调用缓慢挂起。 我也很好奇你在这里如何使用waitpid()。 在我的系统上,waitpid的签名是

 pid_t waitpid(pid_t pid, int *status, int options); 

它看起来像你正在使用wait(),但传递子进程的PID,而不是一个int状态,具有你想测试的状态标志的OR。 这可能会导致一些奇怪的事情发生,我想,如果PID结束被解释为状态掩码。

内核(参数,设备驱动程序,活动模块)和硬件(CPU版本,CPU数量,内存配置,外围设备)差异。

另外:机器在重新启动/重新启动后会改变行为吗?

编辑:

低性能可能与(虚拟)内存层次有关。 这个层次是非常复杂的,这种复杂性可能会导致奇怪的效果。 从TLB到数据缓存到主内存的某个地方可能会发生奇怪的冲突。 这些可能是由于不同机器内核的内存布局略有不同,或者由于内存层次(硬件)实际上稍有不同。

当然,还有其他原因,一个奇怪的外设(产生中断),一个不同的工作量(例如活动进程的数量),…

如果你能解决这个问题,请分享结果! 谢谢。

您是否检查了BIOS配置,以防您的CPU缓存被禁用,或电源配置混乱,或者某些系统过热,或者某些内存被降频…

所有系统的/sbin/sysctl vm.overcommit_memory的值是否相同? 如果不是,那可以解释不同之处。

允许overcommitment会使fork()快得多,但这意味着新分配的页面不会被RAM或交换支持。 如果/当你触摸一个没有备份的页面时,操作系统必须找到它的支持 – 如果不能,这个进程就会被终止。 如果所有子节点都是exec() ,那么这不是问题,因为所有这些unbacked页面都被丢弃; 但是,这可能会导致fork()其他用户出现严重问题。