gpt4 book ai didi

multithreading - nodejs - 我发现多线程或使用多个进程比单个进程慢。为什么?

转载 作者:搜寻专家 更新时间:2023-10-31 22:52:39 25 4
gpt4 key购买 nike

我有一个 CPU 密集型任务(遍历一些数据并评估结果)。我想为此使用多个内核,但我的性能始终比仅使用单个内核差。

我试过:

  • 使用 express 在不同端口上创建多个进程并将任务发送给这些进程
  • 使用webworker-threads使用线程池在不同线程中运行任务

我通过计算我可以完成的迭代总数并除以我在解决问题上花费的时间来衡量结果。使用单核时,我的结果要好得多。

一些兴趣点:

  • 我可以通过任务管理器识别什么时候只使用一个内核,什么时候使用多个内核。我正在使用预期数量的内核。
  • 我有很多内存
  • 我试过只在 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

我也确实尝试了另一种方法,我将发出所有消息,但随后让每个线程监听一条只有它可以回答的消息。例如,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

之后就什么都没有了。

多个快速服务器的更新:我得到了改进,但比预期的要小

我重新审视了这个解决方案并且运气更好。我认为我最初的测量可能有缺陷。新结果:

  • 单进程:3.3 次迭代/秒
  • 主进程 + 2 个服务器:4.2 次迭代/秒
  • 主进程 + 3 个服务器:4.9 次迭代/秒

我发现有点奇怪的一件事是,我没有看到 2 台服务器每秒大约 6 次迭代,3 台服务器每秒 9 次迭代。我知道网络有一些损失,但如果我将任务时间增加到足够高,我认为网络损失应该很小。

最佳答案

您不应该插入您的 Node.js 进程运行多个线程来提高性能。在四核处理器上运行,使用 1 个处理一般请求的 express 进程和处理 CPU 密集型请求的 3 个 express 进程可能是最有效的设置,这就是为什么我建议您尝试设计您的 express 进程以推迟使用 Web worker 并简单地阻塞直到它们产生结果。这将使您按照设计使用单个线程运行单个进程,很可能会产生最佳结果。

我不知道 Web workers 包如何处理同步,影响 c 空间中发生的 Node.js 的 I/O 线程池等的复杂性,但我相信你会通常希望引入 Web worker 以便能够同时管理更多的阻塞任务,而不严重影响不需要线程和系统 I/O 的其他请求,或者可以以其他方式方便地响应。这并不一定意味着应用此方法会改进正在执行的特定任务的性能。如果您运行 4 个进程和 4 个执行 I/O 的线程,您可能会将自己锁定在浪费时间,不断在应用程序空间之外的线程上下文之间切换。

关于multithreading - nodejs - 我发现多线程或使用多个进程比单个进程慢。为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25594140/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com