我有50个机器学习代理。每一帧,他们都会得到一些输入,然后计算神经网络。因为每个代理都是独立的,所以我想让每个代理作为单独的任务来计算网络。
如果我为每个代理,每一帧创建一个任务,这将使我的程序变慢。我试图将我的代理分成两个任务(25和25),但这仍然是一个开销。
在我看来,它是在开始时为n组代理创建n个线程,并以某种方式查询每个帧的线程。线程将计算代理组的网络,然后等待下一次查询。
我读过一些关于这个主题的文章,我发现我不能重用任务。那么,有什么变通方法可以工作呢?
基本上,我在50个代理上有一个重复的操作,即每帧运行大约一分钟,如果不将它们并行化将是一种浪费。
我对多线程和任务仍然是个新手,所以我依赖你的帮助。
旁注:我在Unity中使用了遗传算法。
以下是我试图将代理划分为n组,并在n个任务中计算它们的网络的代码。
public async Task EvaluateAsync(int groupSize = 10)
{
var groups = genomes.Select((g, i) => new { Value = g, Index = i })
.GroupBy(x => x.Index / groupSize)
.Select(x => x.Select(v => v.Value));
var tasks = groups.Select(g =>
{
return Task.Run(() =>
{
foreach (var element in g)
element.Fitness += ComputeFitness(element as NeuralGenome);
});
}).ToArray();
for (var i = 0; i < tasks.Length; i++)
await tasks[i];
}
在Update()
函数中,我调用:
EvaluateAsync(25).Wait();
当网络非常非常大时,它会更快一些,但当只有10个神经元时,它会慢得多。
只有在网络非常庞大的情况下,将组变得更小,才会产生更好的性能。
在这里,我为每个代理创建一个任务:
public async Task EvaluateAsyncEach()
{
var tasks = genomes.Select(x => Task.Run(() => x.Fitness += ComputeFitness(x as NeuralGenome)))
.ToArray();
foreach (var task in tasks)
await task;
}
以下测量是针对10帧进行的。这意味着,t/10将是一个任务的时间。
正常运行时间:
00:00:00.3791190
00:00:00.3758430
00:00:00.3697020
00:00:00.3743900
00:00:00.3764850
每个代理每帧一个任务:
00:00:01.1288240
00:00:01.0761770
00:00:00.9311210
00:00:01.0122570
00:00:00.8938200
以25人为一组:
00:00:00.5401100
00:00:00.5629660
00:00:00.5640470
00:00:00.5932220
00:00:00.6053940
00:00:00.5828170
https://stackoverflow.com/questions/50769215
复制相似问题