我有一个需要占用大量CPU的任务(循环遍历一些数据并评估结果)。我想利用多个核心来完成这项任务,但我的表现始终比仅使用单个核心要差。
我尝试过:
- 使用express在不同端口上创建多个进程,并将任务发送到这些进程中
- 使用webworker-threads在线程池中运行不同线程中的任务
我通过计算完成的迭代总数并除以解决问题所花费的时间来衡量结果。当使用单个核心时,我的结果明显更好。
一些值得注意的点:
- 我可以通过任务管理器识别出我是在使用一个核心还是多个核心。我正在使用预期数量的核心。
- 我有很多RAM
- 我已经尝试过只在2或3个核心上运行
- 我添加了nextTicks,但在这种情况下似乎没有影响
- 每个任务需要几秒钟,因此我不认为我会因开销而损失太多
对于线程的更新:我怀疑webworker-threads中存在一个错误。暂时跳过express,我认为问题可能与我的线程循环有关。我正在做的是创建线程,然后尝试不断运行它们,但在它们之间发送数据。即使两个线程都在使用CPU,也只有线程0返回值。我的假设是emit any通常会将消息发射到空闲时间最长的线程,但事实并非如此。我的设置看起来像这样
在threadtask.js中
thread.on('init', function() {
thread.emit('ready');
thread.on('start', function(data) {
console.log("THREAD " + thread.id + ": execute task");
//...
console.log("THREAD " + thread.id + ": emit result");
thread.emit('result', otherData));
});
});
main.js
var tp = Threads.createPool(NUM_THREADS);
tp.load(threadtaskjsFilePath);
var readyCount = 0;
tp.on('ready', function() {
readyCount++;
if(readyCount == tp.totalThreads()) {
console.log('MAIN: Sending first start event');
tp.all.emit('start', JSON.stringify(data));
}
});
tp.on('result', function(eresult) {
var result = JSON.parse(eresult);
console.log('MAIN: result from thread ' + result.threadId);
//...
console.log('MAIN: emit start' + result.threadId);
tp.any.emit('start' + result.threadId, data);
});
tp.all.emit("init", JSON.stringify(data2));
这场灾难的输出
MAIN: Sending first start event
THREAD 0: execute task
THREAD 1: execute task
THREAD 1: emit result
MAIN: result from thread 1
THREAD 0: emit result
THREAD 0: execute task
THREAD 0: emit result
MAIN: result from thread 0
MAIN: result from thread 0
THREAD 0: execute task
THREAD 0: emit result
THREAD 0: execute task
THREAD 0: emit result
MAIN: result from thread 0
MAIN: result from thread 0
THREAD 0: execute task
THREAD 0: emit result
THREAD 0: execute task
THREAD 0: emit result
MAIN: result from thread 0
MAIN: result from thread 0
我曾尝试另一种方法:发出所有的信息,然后让每个线程监听只有它能回答的信息。例如,线程.on('start' + thread.id, function() { ... })。 但是这种方法行不通,因为当我执行tp.all.emit('start' + result.threadId, ...)时,信息并没有被接收。
MAIN: Sending first start event
THREAD 0: execute task
THREAD 1: execute task
THREAD 1: emit result
THREAD 0: emit result
之后没有发生更多的事情。
针对多个express服务器的更新:我得到了改进,但不如预期的大
我重新审视了这个解决方案,并且有了更好的运气。我认为我的原始测量可能存在缺陷。新结果:
- 单进程:每秒3.3个迭代
- 主进程+2个服务器:每秒4.2个迭代
- 主进程+3个服务器:每秒4.9个迭代
我发现有一件事有点奇怪,那就是我没有看到每秒约6个迭代的2个服务器和每秒9个迭代的3个服务器。我知道网络会有一些损失,但如果我将任务时间增加到足够高的话,网络损失应该很小,我想。
express
创建多个进程?通常情况下,你可以在同一个进程中的不同端口上创建多个服务器。 - Bergi