我有一个非常简单的算法,可以根据它们x
和y
彼此的距离对 blob 进行聚类。我移植了相同的内容以用于Parallel.For
线程本地数据,但结果不正确。换句话说,我可能没有正确使用同步来隔离每个线程。
根本无法弄清楚为什么两种实现的结果不同。任何想法将不胜感激。
我想发布完全可编译的代码,但使用的对象与项目上下文的集成过于紧密。由于该算法非常简单,希望这不会妨碍您。
类级别声明:
/// <summary>
/// Contains the master blobl collection to be clustered.
/// </summary>
public List<Blob> Blobs { get; private set; }
/// <summary>
/// List of clusters to be computed.
/// </summary>
public List<Cluster> Clusters { get; private set; }
线性示例(工作正常):
Cluster cluster = null;
for (int i = 0; i < this.Blobs.Count; i++)
{
cluster = new Cluster();
cluster.Id = i;
if (this.Blobs [i].ClusterId == 0)
{
cluster.Blobs.Add(this.Blobs [i], i);
for (int j = 0; j < this.Blobs.Count; j++)
{
if (this.Blobs [j].ClusterId == 0)
{
if (this.Blobs [i].Rectangle.IntersectsWith(this.Blobs [j].Rectangle))
{
cluster.Blobs.Add(this.Blobs [j], i);
}
else if (this.Blobs [i].Rectangle.IsCloseTo(this.Blobs [j].Rectangle, distanceThreshold))
{
cluster.Blobs.Add(this.Blobs [j], i);
}
}
}
}
if (cluster.Blobs.Count > 2)
{
this.Clusters.Add(cluster);
}
}
并行端口(不正确的集群):
System.Threading.Tasks.Parallel.For<Cluster>
(
0,
this.Blobs.Count,
new ParallelOptions() { MaxDegreeOfParallelism = degreeOfParallelism },
() => new Cluster(),
(i, loop, cluster) =>
{
cluster.Id = i;
if (this.Blobs [i].ClusterId == 0)
{
cluster.Blobs.Add(this.Blobs [i], i);
for (int j = 0; j < this.Blobs.Count; j++)
{
if (this.Blobs [j].ClusterId == 0)
{
if (this.Blobs [i].Rectangle.IntersectsWith(this.Blobs [j].Rectangle))
{
cluster.Blobs.Add(this.Blobs [j], i);
}
else if (this.Blobs [i].Rectangle.IsCloseTo(this.Blobs [j].Rectangle, distanceThreshold))
{
cluster.Blobs.Add(this.Blobs [j], i);
}
}
}
}
return (cluster);
},
(cluster) =>
{
lock (this.Clusters)
{
if (cluster.Blobs.Count > 2)
{
this.Clusters.Add(cluster);
}
}
}
);