线程安全Parallel.For c#

时间:2015-05-29 07:32:03

标签: c# multithreading for-loop parallel-processing

im frenchi很抱歉先抱歉我的英语。

我在visual studio上有一个错误(索引超出范围)我有这个问题只有一个Parallel.For没有经典for。

我认为一个线程想要访问我的数组[i],另一个线程也想要...

这是用于在文档之间建立链接(具有余弦相似性)的calcul Kmeans聚类的代码。

更多信息:

  • IndexOutOfRange是关于similarityMeasure [i] = .....

  • 我的计算机有2个处理器(12logical)

  • 使用经典for,cpu使用率为9-14%,1次迭代的时间= 9min ..

  • 使用parallel.for,cpu使用率为70-90%= p,1次迭代的时间= ~1min30

  • 有时它会在生成错误之前工作更长时间

我的功能是:

    private static int FindClosestClusterCenter(List<Centroid> clustercenter, DocumentVector obj)
{
    float[] similarityMeasure = new float[clustercenter.Count()];
    float[] copy = similarityMeasure;
    object sync = new Object();

  Parallel.For(0, clustercenter.Count(), (i) =>      //for(int i = 0; i < clustercenter.Count(); i++)  Parallel.For(0, clustercenter.Count(), (i) =>  //
       {
                similarityMeasure[i] = SimilarityMatrics.FindCosineSimilarity(clustercenter[i].GroupedDocument[0].VectorSpace, obj.VectorSpace);

       });

    int index = 0;
    float maxValue = similarityMeasure[0];
    for (int i = 0; i < similarityMeasure.Count(); i++)
    {
        if (similarityMeasure[i] > maxValue)
        {
            maxValue = similarityMeasure[i];
            index = i;
        }

    }
    return index;
}

我的功能是在这里打电话:

do
            {
                prevClusterCenter = centroidCollection;
                DateTime starttime = DateTime.Now;

                  foreach (DocumentVector obj in documentCollection)//Parallel.ForEach(documentCollection, parallelOptions, obj =>//foreach (DocumentVector obj in documentCollection)
                   {

                       int ind = FindClosestClusterCenter(centroidCollection, obj);

                       resultSet[ind].GroupedDocument.Add(obj);

                   }
                TimeSpan tempsecoule = DateTime.Now.Subtract(starttime);
                Console.WriteLine(tempsecoule);
                //Console.ReadKey();
                InitializeClusterCentroid(out centroidCollection, centroidCollection.Count());
                centroidCollection = CalculMeanPoints(resultSet);
                stoppingCriteria = CheckStoppingCriteria(prevClusterCenter, centroidCollection);
                if (!stoppingCriteria)
                {
                    //initialisation du resultat pour la prochaine itération
                    InitializeClusterCentroid(out resultSet, centroidCollection.Count);
                }
            } while (stoppingCriteria == false);
            _counter = counter;
            return resultSet;

FindCosSimilarity:

 public static float FindCosineSimilarity(float[] vecA, float[] vecB)
        {
            var dotProduct = DotProduct(vecA, vecB);
            var magnitudeOfA = Magnitude(vecA);
            var magnitudeOfB = Magnitude(vecB);
            float result = dotProduct / (float)Math.Pow((magnitudeOfA * magnitudeOfB),2);
            //when 0 is divided by 0 it shows result NaN so return 0 in such case.
            if (float.IsNaN(result))
                return 0;
            else
                return (float)result;

        }

CalculMeansPoint:

 private static List<Centroid> CalculMeanPoints(List<Centroid> _clust)
        {
            for (int i = 0; i < _clust.Count(); i++)
            {
                if (_clust[i].GroupedDocument.Count() > 0)
                {
                    for (int j = 0; j < _clust[i].GroupedDocument[0].VectorSpace.Count(); j++)
                    {
                        float total = 0;
                        foreach (DocumentVector vspace in _clust[i].GroupedDocument)
                        {
                            total += vspace.VectorSpace[j];
                        }

                        _clust[i].GroupedDocument[0].VectorSpace[j] = total / _clust[i].GroupedDocument.Count();
                    }
                }
            }
            return _clust;
        }

2 个答案:

答案 0 :(得分:1)

您可能在primary中有一些副作用,请确保它不会修改任何字段或输入参数。示例:FindCosineSimilarity。如果resultSet[ind].GroupedDocument.Add(obj);不是对本地实例化数组的引用,那么这是side effect

这可能会解决它。但是,仅供参考,您可以使用resultSet而不是AsParallel

Parallel.For

答案 1 :(得分:0)

你意识到,如果你同步Parallel-For的整个内容,它就像正常的for-synch同步一样,对吧?意思是代码并不是并行执行任何操作,所以我不认为你会遇到任何并发问题。我的猜测是clustercenter[i].GroupedDocument可能是一个空数组。