X、Y 空間に多数のParticle
s があり、平均 X と Y が 0 になるようにすべてを正規化するとします。
シリアル実装:
public void Normalise()
{
double avgX = 0.0;
double avgY = 0.0;
foreach (Particle p in Particles)
{
avgX += p.X;
avgY += p.Y;
}
avgX /= (double)Particles.Count;
avgY /= (double)Particles.Count;
foreach (Particle p in Particles)
{
p.X -= avgX;
p.Y -= avgY;
}
}
これは機能し、O(n) であるためパフォーマンスは悪くありませんが、「恥ずかしいほど並列」です。私の PLINQ 実装を見てください。
public void PNormalise()
{
double avgX = 0.0;
double avgY = 0.0;
Particles.AsParallel().ForAll(p =>
{
avgX += p.X;
avgY += p.Y;
});
avgX /= (double)Particles.Count;
avgY /= (double)Particles.Count;
Particles.AsParallel().ForAll(p =>
{
p.X -= avgX;
p.Y -= avgY;
});
}
ここでのパフォーマンスについてはよくわかりませんが、それよりも優れていると思います。問題は、パーティクルがすべてランダムに飛び回っていることです。+=
と の操作は、すでにかなりアトミックになっていますが、互いに競合しているavgX
としか思えません。avgY
それを修正するためにできることはありますか?それらはオブジェクトではないのでできませんlock
が、ロックはかなり高価ではないので、とにかくやりたいかどうかわかりませんか?