主线程和Web工作者之间的转移很慢

时间:2017-07-01 15:22:14

标签: javascript multithreading web-worker

我的主线程和webworker之间的通信非常慢,所以我看了this question,它告诉我如何使用缓冲区来使通信速度几乎看不到。

对于包含与我的示例中相同类型的90000000元素的数组,该问题的回答为0.4ms。

该代码正在使用Neataptic设置的神经进化算法中评估基因组,以了解它们在MNIST数据集上的表现如何,但它不应成为问题的一部分。

我只有一个只有397000元素的数组,通讯时间在30到50毫秒之间。 This is a JSFiddle of my code(打开控制台) - 也在这里:

/** Rename vars */
var Neat    = neataptic.Neat;
var Methods = neataptic.Methods;
var Config  = neataptic.Config;

/** Turn off warnings */
Config.warnings = false;

function createWorker(network, cost){
  // source is equivalent of test(), but without time recording
  var source = `
  ${network.standalone()}

  var cost = ${cost.toString()}
  onmessage = function(e) {
    console.log('Message received at', performance.now());
    var set = new Float64Array(e.data);
    var ins = set[0];
    var out = set[1];

    var error = 0;
    // Calculate how much samples are in the set
    for(var i = 0; i < (set.length - 2) / (ins + out); i++){
      let input = [];
      let target = [];
      for(var j = 2 + i * (ins + out); j < 2 + i * (ins + out) + ins; j++){
        input.push(set[j]);
      }
      for(var j = 2 + i * (ins + out) + ins; j < 2 + i * (ins + out) + ins + out; j++){
        target.push(set[j]);
      }

      let output = activate(input);
      error += cost(target, output);
    }

    var answer = new Float64Array([error / ((set.length - 2) / (ins + out))]);
    postMessage(answer.buffer, [answer.buffer]);
  }
  `;

  var blob = new Blob([source]);
  var blobURL = window.URL.createObjectURL(blob);
  var worker = new Worker(blobURL);

  return worker;
}

async function multiEvaluate(population, dataSet, cost){
  // Prepare the dataset to create a buffer
  var converted = [dataSet[0].input.length, dataSet[0].output.length];

  for(var i = 0; i < dataSet.length; i++){
    for(var j = 0; j < converted[0]; j++){
      converted.push(dataSet[i].input[j]);
    }
    for(var j = 0; j < converted[1]; j++){
      converted.push(dataSet[i].output[j]);
    }
  }

  return new Promise((resolve, reject) => {
    // Keep track of how many workers are finished
    var counter = 0;

    // Create a worker for every network, post a message
    for(var i = 0; i < population.length; i++){
      let genome = population[i];
      let worker = createWorker(genome, cost);
      worker.onmessage = function(e){
        genome.score = new Float64Array(e.data)[0];
        worker.terminate();
        if(++counter == population.length){
          resolve()
        }
      }

      let temp = new Float64Array(converted);
      console.log('Message sent at', performance.now());
      worker.postMessage(temp.buffer, [temp.buffer]);
    }
  });
}

async function f() {
  var network= new neataptic.Network(784,10);

  for(var i = 0; i < network.connections.length; i++){
    network.connections[i].weight = Math.random() * .02 - .01;
  }

  var neat = new neataptic.Neat(784, 10, null, {popsize: 1, network: network});
  for(var i = 0; i < 10; i++) neat.mutate();

  var set = mnist.set(500, 0).training;
  await multiEvaluate(neat.population, set, Methods.Cost.MSE);
}

f();

有谁知道为什么我的代码中的通信时间太慢而不是其他问题代码?

编辑:当我增加工作人员的数量时,邮件的最后一次到达将在邮件的最后一次出发后...似乎网络工作者不要这样做在发布所有消息后开始运行

0 个答案:

没有答案