Communication between my main thread and the webmaster was very slow, so I considered this question , which described how to use buffers for communication, the speed is almost apparent.
The answer to this question is 0.4 ms for an array containing elements of 90000000the same type as in my example.
The code evaluates the genomes in the neuroevolution algorithm installed with Neataptic to see how well they perform in the MNIST dataset, but it should not be part of the problem.
I just have an array with only 397000elements, and the communication time varies from 30 to 50 ms. This is the JSFiddle of my code (open console) - also here:
var Neat = neataptic.Neat;
var Methods = neataptic.Methods;
var Config = neataptic.Config;
Config.warnings = false;
function createWorker(network, cost){
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;
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){
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) => {
var counter = 0;
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();
Does anyone know why the communication time in my code is so slow and not in another question code?
Edit: when I increase the number of workers to start, the first arrival of the message will be after the last message was sent ... it looks like web users do not start after all messages have been sent