节点的子进程是否“更慢”?

时间:2016-04-25 15:28:03

标签: javascript node.js child-process

考虑以下代码来近似pi:

// filename: pi.js
function approx_pi(from, to) {
    var pi = 0;
    var dx = 0.0000000005;
    for(var x = from; x < to; x += dx) {
        pi += 4 / (1 + x * x);
    }
    return pi * dx;
}

var min = Infinity;
var max = -1;
var avg = 0;

for(var itr = 0; itr < 10; ++itr) {
    var start = process.hrtime();
    var pi = approx_pi(0, 1);
    var diff = process.hrtime(start);

    var duration = diff[0] + diff[1] * 1e-9;

    min = (duration <= min) ? duration : min;
    max = (duration >= max) ? duration : max;
    avg += duration;
}

avg /= 10;

min = min.toFixed(3);
max = max.toFixed(3);
avg = avg.toFixed(3);

console.log("Time: min = %ss, max = %ss , avg = %ss", min, max, avg);

还要考虑在n个子进程中运行上述文件的代码,而n是通过命令行参数提供的:

//filename: children.js
var cp = require('child_process');

var n = parseInt(process.argv[2]);

for(var k = 0; k < n; ++k) {
    cp.fork('pi.js');
}

运行node pi.js时输出为:

Time: min = 19.113s, max = 22.220s , avg = 21.152s

类似的结果来自于运行node children.js 1(预期)

Time: min = 17.323s, max = 21.465s , avg = 19.979s

当多个孩子分叉时,东西开始变得奇怪(至少是我自己的期望)。以下是运行node children.js 2后的输出:

Time: min = 29.824s, max = 41.050s , avg = 35.136s
Time: min = 30.036s, max = 40.791s , avg = 35.246s

每个孩子至少比单个版本多花了14秒。运行node children.js 4的4个孩子时情况更糟,每个孩子花了大约37秒才完成:

Time: min = 55.878s, max = 68.047s , avg = 58.845s
Time: min = 52.760s, max = 69.168s , avg = 58.880s
Time: min = 57.151s, max = 69.113s , avg = 58.956s
Time: min = 50.790s, max = 70.344s , avg = 59.546s

这些测试在Core i5 2410M CPU @ 2.30GHz(操作系统可见4个核心)的计算机上运行,​​4GB RAM同时运行:Windows 7运行节点v4.2.3和Ubuntu14.04运行节点v5.4.1 。每个操作系统显示每个孩子都在自己的核心上运行,每个孩子都有相同数量的内存(大约9MB)。

根据节点文档here“每个进程都有自己的内存,有自己的V8实例”。因此,人们会期望每个孩子的表现应该与单个过程一样好。

我的期望是否被误导,这是预期的行为或正在发生的事情?

1 个答案:

答案 0 :(得分:2)

您在具有2 cores (4 threads)的CPU上并行运行4个进程,然后测量实际时间而不是CPU时间。当然,每个过程都需要更长时间......您无法在有限数量的内核上运行无限数量的进程,并且期望运行时与在多个内核上运行单个进程相同。 (如果有人想出如何做到这一点,那么网络安全就是干杯。)

您可能希望在2个核心上运行的2个进程与单个进程(必须在单个核心上运行)同时运行,但实际情况通常与理论不完全相同。您的2个进程实际上在同一核心上实际共享时间的可能性很大。没有简单的方法可以保证每个流程都能获得它自己的核心,因为这些细节几乎总是从你的控制中抽象出来。