并行聚合多个双打

时间:2013-01-30 10:07:43

标签: c# parallel-processing

如何将聚合多个双精度的循环并行化?

可以将两个或多个Parallel.For循环执行此操作,其中单个双精度求和,但在我的情况下,这将需要重复两个变量共有的昂贵函数。

单线程形式的简化示例:

static void Main()
{
    double sum1 = 0.0;
    double sum2 = 0.0;
    for (int i = 2; i < 10; i++)
    {
        double result = function1(i);
        sum1 += result;
        sum2 += function2(result);
    }
    Console.WriteLine(sum1 + " " + sum2);
    Console.ReadLine();
}

private static double function1(int x)
{
    return Math.Exp((double)x);
}

private static double function2(double x)
{
    return Math.Pow(x, 2);
}

此处的功能1和2实际上非常昂贵,因此只能评估一次。

我找到的用于聚合一个双精度的代码:

        object lockObject = new object();
        double sum = 0.0d;

        Parallel.For(0, 10,
            () => 0.0d,

            (x, loopState, partialResult) =>
            {
               return (double)x / 100.0 + partialResult;
            },

            (localPartialSum) =>
            {
               lock (lockObject)
               {
                 sum += localPartialSum;
               }
            });

1 个答案:

答案 0 :(得分:1)

您可以将Parallel.For与线程本地数据一起使用:

object sync = new object();
double sum1 = 0.0;
double sum2 = 0.0;
Parallel.For<Tuple<double, double>>(2, 10,
    () => { return new Tuple<double, int>(0.0, 0.0); },
    (i, pls, state) =>
    {
        double result = function1(i);
        state = new Tuple<double, double>( state.Item1 + result, state.Item2 + function2(result))
        return state;
    },
    state => { lock (sync) { sum1 += state.Item1; sum2 += state.Item2; } }
);

如果您使用包含两个double而不是Tuple的可变类,则可以稍微简化一下代码。