如何使用并行subprocess在大型数组上执行“工作”?

我有一大堆数字。 我想要使​​用JavaScript / Node.js来计算所有数字的总和。 (就这个问题而言,这是一个简单的总和;实际上我有一个更复杂和更冗长的math运算来执行)。

在单线程的世界中,计算总和需要很长时间。 为了更快速地处理结果,我一直在尝试将工作委托给多个并行运行的subprocess。 每个subprocess确定一个子数组的总和,并且在父进程中总计一切。

我的两个脚本如下:

index.js

function computeSum(data) { var start = new Date(); var sum = data.reduce(function(a, b) { return a + b; }); console.log("Sum = %s, Time = %s ms", sum, new Date().getTime() - start.getTime()); } function computeSumConcurrent(data) { var child_process = require("child_process"); var os = require("os"); var cpuCount = os.cpus().length; var subArraySize = data.length / cpuCount; var childProcessesFinished = 0; var start = new Date(); var sum = 0; for (var i = 0; i < cpuCount; i++) { var childProcess = child_process.fork("child.js"); childProcess.on("message", function(message) { sum += message.sum; childProcessesFinished++; if (childProcessesFinished == cpuCount) { console.log("Sum = %s, Time = %s ms", sum, new Date().getTime() - start.getTime()); process.exit(); } }); childProcess.send({ subArray: data.slice(subArraySize * i, subArraySize * (i + 1)) }); } } console.log("Populating array..."); var data = [] for (var i = 0; i < 50000000; i++) { data.push(Math.random()); } console.log("Computing sum without using child processes..."); computeSum(data); console.log("Computing sum using child processes..."); computeSumConcurrent(data); 

child.js

 process.on("message", function(message) { var sum = message.subArray.reduce(function(a, b) { return a + b; }); process.send({ sum: sum }); process.exit(); }); 

如果你运行index.js,你会发现并行总和非常慢。 我想这可能是由于childProcess.send ,这并不意味着要传递大量的数据 ,但我不完全确定。

那么这种事情的解决scheme是什么? 如何使并行总和比单线程更快?

创build用于小型工作的subprocess以及发送和接收消息实际上可以增加持续时间或处理,因为发送和接收消息需要时间。

还有一个问题,在你的代码中,你实际上是将subprocess从主进程本身分离出来,这不会让你的主进程免于工作,而只是增加它。

我会build议你另一种方法。

  1. 创build一个subprocess发送它的所有数据。

  2. 让孩子自己创造其他孩子,并给他们分配工作。 然后计算所有的结果。

  3. 将最终结果发送给父母。

注意:

  1. 确保你不要创造太多的孩子,并给他们分配很小的工作。 这只会让你发送和接收太多的消息,从而会延误处理。

  2. 也不要创造太less的孩子叉,他们自己需要太多时间处理给定的任务。

  3. 您必须确保任何subprocess在它自己创build的subprocess之前不会退出

优点:

  1. 你的主stream程不会忙于分工和计算结果。
  2. 很多分叉的孩子会在相对较短的时间内完成任务(我不会说很短的时间)

随意问你是否需要一些例子。

Interesting Posts