1

It prints correct result 4.5 with the same probability as 0.1, 0.2, 1, 2.3 and etc. What is wrong with it?

double average = 0;

Parallel.ForEach(
    Enumerable.Range(0, 10),
    () => 0,
    (elem, loopState, localSum) => {
        localSum += elem;
        return localSum;
    },
    localSum => {
        double localAvg = localSum / 10.0;
        Interlocked.Exchange(ref average, localAvg);
    }
);

Console.WriteLine($"Average in parallel manner: {average}");

For example:

Average in parallel manner: 0,2

Average in parallel manner: 3,2

Average in parallel manner: 1,2

But everything is OK when I use the similar code with Interlocked.Add():

int totalSum = 0;

Parallel.For(0, 10, () => 0, (ind, loopState, local) => {
    local += ind;
    return local;
},
local => Interlocked.Add(ref totalSum, local));

Console.WriteLine($"Total sum in parallel manner: {totalSum}");
Community
  • 1
  • 1

1 Answers1

1

Well, if you exchange temporary local results for the end result instead of adding them up, you get a wrong result. The function name says as much. I'm not sure why you expect something else to happen.

1 + 2 = 3
3 + 4 = 7
5 + 6 = 11
7 + 8 = 15
9 + 10 = 19

Now if you add them all up you get a correct result. If you take all, in a random order and then pick the last to be your result... that's simply wrong mathematically.

nvoigt
  • 75,013
  • 26
  • 93
  • 142