1

複数のdoubleが集約されるループをどのように並列化するのですか?

これを2つ以上のParallel.Forループとして実行し、1つのdoubleを合計することは可能ですが、私の場合、両方の変数に共通するコストのかかる関数を繰り返す必要があります。

シングルスレッド形式の簡略化された例:

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は実際には非常に高価であるため、一度だけ評価する必要があります。

1つのdoubleを集約するために見つけたコード:

        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;
               }
            });
4

1 に答える 1

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の代わりに2つのsを含む可変クラスを使用する場合はTuple、コードを少し単純化できます。

于 2013-01-30T10:53:40.647 に答える