Javascript 主线程和web worker之间的传输很慢
我的主线程和webworker之间的通信非常慢,所以我看了一下它告诉我如何使用缓冲区,使通信速度看起来几乎没有什么变化 对于包含与我的示例中相同类型的Javascript 主线程和web worker之间的传输很慢,javascript,multithreading,web-worker,Javascript,Multithreading,Web Worker,我的主线程和webworker之间的通信非常慢,所以我看了一下它告诉我如何使用缓冲区,使通信速度看起来几乎没有什么变化 对于包含与我的示例中相同类型的90000000元素的数组,该问题的答案是0.4ms的通信 这段代码正在用神经进化算法对基因组进行评估,该算法设置为,以查看它们在MNIST数据集上的表现如何,但这不应该是问题的一部分 我只是有一个数组,其中只有397000个元素,通信时间在30到50毫秒之间变化。(打开控制台)-此处也包括: /** Rename vars */ var Neat
90000000
元素的数组,该问题的答案是0.4ms的通信
这段代码正在用神经进化算法对基因组进行评估,该算法设置为,以查看它们在MNIST数据集上的表现如何,但这不应该是问题的一部分
我只是有一个数组,其中只有397000
个元素,通信时间在30到50毫秒之间变化。(打开控制台)-此处也包括:
/** 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();
/**重命名变量*/
var Neat=neatatic.Neat;
var方法=neataptic.方法;
var Config=neataptic.Config;
/**关闭警告*/
Config.warnings=false;
功能createWorker(网络、成本){
//源相当于test(),但没有时间记录
变量源=`
${network.standalone()}
var cost=${cost.toString()}
onmessage=函数(e){
log('messagereceivedth',performance.now());
变量集=新的浮点数组(如数据);
var-ins=set[0];
var out=设定值[1];
var误差=0;
//计算集合中有多少样本
对于(变量i=0;i<(set.length-2)/(ins+out);i++){
让输入=[];
让目标=[];
对于(变量j=2+i*(ins+out);j<2+i*(ins+out)+ins;j++){
input.push(设置[j]);
}
对于(变量j=2+i*(ins+out)+ins;j<2+i*(ins+out)+ins+out;j++){
target.push(设置[j]);
}
让输出=激活(输入);
误差+=成本(目标、产出);
}
var answer=newfloat64array([error/((set.length-2)/(ins+out)));
postMessage(answer.buffer,[answer.buffer]);
}
`;
var blob=新blob([来源]);
var blobURL=window.URL.createObjectURL(blob);
var工人=新工人(blobURL);
返乡工人;
}
异步函数多重评估(总体、数据集、成本){
//准备数据集以创建缓冲区
var converted=[dataSet[0].input.length,dataSet[0].output.length];
对于(var i=0;i{
//记录完成的工人数量
var计数器=0;
//为每个网络创建一个worker,发布消息
对于(变量i=0;i
有人知道为什么在我的代码中,而在其他问题代码中,通信时间如此之慢吗
编辑:当我增加要启动的工作人员数量时,消息的第一次到达将在消息的最后一次离开之后。。。所有消息发布后,webworkers似乎不会开始运行您正在尝试创建100个workers?是的,它们无法开始运行,因为用于创建辅助对象的JavaScript代码是同步的。即使是异步的,100个工作者(线程)也太多了。@Cristy不,我只创建了1个,我注意到通信延迟非常严重。我刚刚对100名工人做了一个小测试,我注意到第一个测试是在最后一个得到指示后才进行的。但是,请关注1工作者的例子。那么,您能否只发布一个工作者的代码并去除不必要的位?你说的“沟通缓慢”是什么意思?实际创建工作程序可能需要几毫秒的时间。@Cristy问题中的代码仅适用于一个工作程序。我知道创建它需要几毫秒的时间,但我只是测量消息离开和消息到达之间的时间(在运行问题中链接的JSFIDLE时打开控制台),它对于缓冲数据来说太大了。@哦,我以为您在代码末尾指的是
t0
和t1
。