Webworkers的多线程效率低下吗? [英] Is multithreading with webworkers ineffective?

查看:48
本文介绍了Webworkers的多线程效率低下吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个项目,其中我必须处理相当大的对象,每个对象大约需要500毫秒.我认为使用网络工作者会大大加快这一过程.但是在和网络工作者一起玩耍之后,即使我取消了对网络工作者创建的预处理,他们似乎也根本没有提高速度.

因此,我决定创建一个简单的示例:存在一个具有 N 个数字的数组,并且应该计算这些数字的总和.

因此,首先,没有网络工作人员( 演示> ):

 /**目标:返回数组中所有数字的总和*/变数= [];for(var i = 0; i< N; i ++){number.push(Math.floor(Math.random()* 100));}/**在没有网络工作者的情况下进行测试*/var total = 0;for(var i = 0; i< numbers.length; i ++){总数+ =数字[i];} 

然后,网络工作人员( 演示):

 /**选项*/var WORKERS = 5;//N应该被工人整除/**与网络工作者一起测试*/var workers = [];var source =`onmessage = function(e){var total = 0;for(var i = 0; i< e.data.length; i ++){总数+ = e.data [i];}postMessage(总计);}`for(var i = 0; i< WORKERS; i ++){var blob = new Blob([source]);var blobURL = window.URL.createObjectURL(blob);让worker = new Worker(blobURL);worker.onmessage = function(e){总计+ = e.data;worker.terminate();if(++完成== worker.length)done();}worker.push(工人);}var finish = 0;var chunk = Math.floor(N/WORKERS);var sliced = [];for(var i = 0; i< worker.length; i ++){sliced.push(numbers.slice(i * chunk,i * chunk + chunk));}//我们从这里计算出创建工人后的时间var total = 0;for(var i = 0; i< worker.length; i ++){worker [i] .postMessage(sliced [i]);}函数done(){//做一点事} 

因此,结果:网络工作者似乎完全是灾难性的.比没有网络工作者要慢十倍以上.

所以我的问题是,有谁能向我展示一个使用Webworkers进行多线程实际上更快的示例吗?除了运行而不影响UI之外,我看不到Webworkers的意义.

,它的运行速度较慢,但​​是CPU使用率却更高(如果使用,则为100%,如果不使用Webworker,则为〜30%)-这使我怀疑所有功能都在哪里

即使您将 onmessage 留在工作端也无济于事,但它的运行速度仍然很慢……似乎主线程之间的通信而且工作线程的运行速度非常慢(自己动手)

,它与 postMessage 无关,我已经评估了性能,通过编码不同我无能为力.最奇怪的事情:当我使用Google chrome开发工具衡量性能时,它的运行速度几乎快了2倍

有趣的文章:

解决方案

您的基准测试被向每个工作人员转移一千万个数字的成本所淹没.

相反,创建一个 ArrayBuffer .将其作为 transferList ( postMessage 的第二个参数)的一部分传递.在我的机器上,工人在不到100毫秒内完成这项工作,而没有工人在200毫秒内完成工作.

请参见 https://jsfiddle.net/ooduhb5h/7/.

I have a project in which I have to process quite large objects, each taking about 500ms. I thought that using web workers would greatly speed up this process. But after playing around with web workers, they didn't seem to improve the speed at all - even if I took away the preprocessing the creation of the web workers.

So I decided to create a simple example: there is an array with N numbers, and the sum of those numbers should be calculated.

So first, without webworkers (DEMO):

/** Goal: return sum of all numbers in array */
var numbers = [];

for(var i = 0; i < N; i++){
    numbers.push(Math.floor(Math.random() * 100));
}

/** Test without web workers */
var total = 0;
for(var i = 0; i < numbers.length; i++){
    total += numbers[i];
}

Then, with webworkers (DEMO):

/** Options */
var WORKERS = 5; // N should be divisble by WORKERS

/** Test WITH web workers */
var workers = [];

var source = `
onmessage = function(e) {
    var total = 0;
    for(var i = 0; i < e.data.length; i++){
    total += e.data[i];
  }
    postMessage(total);
}`

for(var i = 0; i < WORKERS; i++){
  var blob = new Blob([source]);
  var blobURL = window.URL.createObjectURL(blob);
  let worker = new Worker(blobURL);

  worker.onmessage = function(e){
    total += e.data;
    worker.terminate();
    if(++finished == workers.length) done();
  }

  workers.push(worker);
}

var finished = 0;
var chunk = Math.floor(N / WORKERS);

var sliced = [];
for(var i = 0; i < workers.length; i++){
    sliced.push(numbers.slice(i*chunk,i*chunk+chunk));
}

// we calculate time after we created the workers, from here
var total = 0;
for(var i = 0; i < workers.length; i++){
  workers[i].postMessage(sliced[i]);
}

function done(){
  // do something
}

So the results: webworkers seem to be completely disastrous. It's over 10x slower than without webworkers.

So my question, can anyone show me an example where multithreading with webworkers is actually faster? I'm failing to see the point of webworkers besides running without affecting the UI....

Edit: it runs over way slower, but the CPU usage is way higher (100% with, ~30% without webworkers) - it makes me question where all that power is going to

Edit 2: Even when you leave the onmessage on the worker side do nothing, it still runs way slower... it seems like the communication between the main thread and the worker thread is just incredibly slow (see for yourself)

Edit 3: it's not related to postMessage, I have measured performance and it's nothing I can do about by coding differently. The weirdest thing of all: when I measure performance with Google chrome dev tools, it runs almost 2x as fast

Interesting article:

解决方案

Your benchmark is being swamped by the cost of transferring ten million numbers to each worker.

Instead, create a ArrayBuffer. Pass that, as part of transferList (the second parameter to postMessage). On my machine the workers run this job in less than 100ms compared to 200ms without the workers.

See https://jsfiddle.net/ooduhb5h/7/.

这篇关于Webworkers的多线程效率低下吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆