假设我在 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
,因为它们不是对象,但我不确定我是否想要,因为锁定不是很昂贵吗?