并行聚合多个双精度

本文关键字:双精度 并行 | 更新日期: 2023-09-27 17:56:50

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

可以将其执行为两个或多个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;
               }
            });

并行聚合多个双精度

您可以将

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,则可以稍微简化代码。