Parallel processing and further use of output

anonymous via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sat Sep 26 05:33:44 PDT 2015


On Saturday 26 September 2015 14:18, Zoidberg wrote:

> I've run into an issue, which I guess could be resolved easily, 
> if I knew how...
> 
> [CODE]
>      ulong i = 0;
>      foreach (f; parallel(iota(1, 1000000+1)))
>      {
>          i += f;
>      }
>      thread_joinAll();
>      i.writeln;
> [/CODE]
> 
> It's basically an example which adds all the numbers from 1 to 
> 1000000 and should therefore give 500000500000. Running the above 
> code gives 205579930677, leaving out "thread_joinAll()" the 
> output is 210161213519.
> 
> I suspect there's some sort of data race. Any hint how to get 
> this straight?

Definitely a race, yeah. You need to prevent two += operations happening 
concurrently.

You can use core.atomic.atomicOp!"+=" instead of plain +=:
----
    shared ulong i = 0;
    foreach (f; parallel(iota(1, 1000000+1)))
    {
        import core.atomic: atomicOp;
        i.atomicOp!"+="(f);
    }
----
i is shared because atomicOp requires a shared variable. I'm not sure what 
the implications of that are, if any.

Alternatively, you could use `synchronized`:
----
    ulong i = 0;
    foreach (f; parallel(iota(1, 1000000+1)))
    {
        synchronized i += f;
    }
----
I'm pretty sure atomicOp is faster, though.


More information about the Digitalmars-d-learn mailing list