假设我有许多在X,Y空间中的“粒子”,我想将它们全部归一化,使得平均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
上的 +=
操作彼此竞争,即使它们已经相当原子化。
有什么办法可以解决吗?我不能锁定它们,因为它们不是对象,但我也不确定是否要锁定,因为锁定非常昂贵,是吗?