并行用于c#

mig*_*mpn 2 c# parallel.foreach

我正在尝试提高计算图像平均值的方法的性能.

为此,我使用两个For语句来迭代所有图像,因此我尝试使用Parallel For来改进这一点,但结果并不相同.

我做错了吗?或者是什么导致了这种差异?

public static double MeanDN(this GrayImage image)
{
  double mean = 0;
  int totalPixels = image.Width * image.Height;

  for (int i = 0; i < image.Height; i++)
      for (int j = 0; j < image.Width; j++)
          mean += (double)image[i, j] / totalPixels;

  double parallelMean = 0;

  Parallel.For(0, image.Height, i =>
  {
      for (int j = 0; j < image.Width; j++)
          parallelMean += (double)image[i, j] / totalPixels;
  });

  return mean;
}
Run Code Online (Sandbox Code Playgroud)

输出:

mean = 404.12

parallelMean = 148.8658

nvo*_*igt 5

您正在访问资源(变量parallelMean)而没有来自多个线程的同步.某些更改将相互覆盖,某些读取将读取错误或旧数据.这就是你看到错误结果的原因.

最简单的解决方案是lock围绕对该变量的写访问进行声明,但这会强制它重新执行它.

如果您需要对结果进行计算,则可能更容易使用PLinq,它为您执行大部分同步:

var mean = Enumerable.Range(0, image.Height)
                     .AsParallel()
                     .Select(i => Enumerable.Range(0, image.Width)
                                            .AsParallel()
                                            .Sum(j => (double)image[i, j] / totalPixels))
                     .Sum();
Run Code Online (Sandbox Code Playgroud)