i8a*_*bug 5 performance multithreading web-worker node.js express
我有一个CPU密集型任务(循环一些数据和评估结果).我想为这些使用多个内核,但我的性能始终比仅使用单个内核更糟糕.
我试过了:
我通过计算我可以完成的迭代总数并除以我处理问题所花费的时间来测量结果.使用单核时,我的结果明显更好.
一些兴趣点:
想知道这里发生了什么?
更新线程:我怀疑webworker-threads中的一个错误 现在跳过快递,我认为这个问题可能与我的线程循环有关.我正在做的是创建一个线程,然后尝试连续运行它们,但在它们之间来回发送数据.即使两个线程都在耗尽CPU,但只有线程0返回值.我的假设是发出任何通常最终将消息发送到空闲时间最长的线程,但似乎并非如此.我的设置看起来像这样
在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));
});
});
Run Code Online (Sandbox Code Playgroud)
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));
Run Code Online (Sandbox Code Playgroud)
输给这场灾难
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
Run Code Online (Sandbox Code Playgroud)
我确实尝试了另一种方法,我将发出所有,然后让每个线程听取只有它可以回答的消息.例如,thread.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
Run Code Online (Sandbox Code Playgroud)
之后再也没有发生过.
多个快递服务器的更新:我正在改进,但比预期的要小
我重新审视了这个解决方案并且运气更好.我认为我的原始测量可能存在缺陷.新结果:
有一件事我觉得有点奇怪的是,我没有看到2台服务器大约6次迭代/秒和9次3次.我知道网络有一些损失但是如果我将任务时间增加到足够高,那么网络我想,损失应该很小.
您不应该推动 Node.js 进程运行多个线程来提高性能。在四核处理器上运行,有 1 个express进程处理一般请求,3 个express进程处理 CPU 密集型请求可能是最有效的设置,这就是为什么我建议您尝试设计express进程以推迟使用 Web Worker 和只需阻塞直到产生结果。这将使您根据设计使用单个线程运行单个进程,很可能会产生最佳结果。
我不知道 Web Workers 包如何处理同步、影响c太空中发生的 Node.js I/O 线程池等的复杂性,但我相信您通常会希望引入 Web Workers 来管理同时处理更多的阻塞任务,而不会严重影响不需要线程和系统 I/O 的其他请求,或者可以方便地响应。这并不一定意味着应用此功能会提高正在执行的特定任务的性能。如果您运行 4 个进程,其中有 4 个执行 I/O 的线程,您可能会陷入浪费时间在应用程序空间之外的线程上下文之间不断切换的情况。