Simplest multithreading example
Brian via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Mon Sep 4 18:15:41 PDT 2017
On Friday, 1 September 2017 at 20:02:23 UTC, ag0aep6g wrote:
> On 09/01/2017 07:27 AM, Brian wrote:
>> double [] hugeCalc(int i){
>> // Code that takes a long time
>> }
>>
>> so if I do
>>
>>
>> double[][int] _hugeCalcCache;
>> foreach(i ; I)
>> _hugeCalcCache[i] = hugeCalc(i);
>>
>> of course the required time is I.length * (a long time), so I
>> wanted to shorten this by splitting to different threads :
>>
>> foreach(i ; parallel(I) )
>> _hugeCalcCache[i] = hugeCalc(i);
>>
>> but as you can guess, it doesn't work that easily.
>
> Works pretty well for me:
>
> ----
> double [] hugeCalc(int i)
> {
> // Code that takes a long time
> import core.thread: Thread;
> import std.datetime: seconds;
> Thread.sleep(1.seconds);
> return [i];
> }
>
> void main()
> {
> static import std.range;
> import std.parallelism: parallel;
> auto I = std.range.iota(0, 10);
> double[][int] _hugeCalcCache;
> foreach(i ; parallel(I))
> _hugeCalcCache[i] = hugeCalc(i);
> }
> ----
>
> That runs in about 3 seconds here. The serial version would of
> course take about 10 seconds. So, parallelism achieved!
>
> Though I don't know if it's safe to access an associative array
> concurrently like that. I'd use a normal dynamic array instead
> and initialize it before going parallel:
>
> ----
> auto _hugeCalcCache = new double[][](10);
> ----
Thanks very much for your help, I finally had time to try your
suggestions. The initial example you showed does indeed have the
same problem of not iterating over all values :
double [] hugeCalc(int i){
// Code that takes a long time
import core.thread: Thread;
import std.datetime: seconds;
Thread.sleep(1.seconds);
return [i];
}
static import std.range;
import std.parallelism: parallel;
auto I = std.range.iota(0, 100);
double[][int] _hugeCalcCache;
foreach(i ; parallel(I))
_hugeCalcCache[i] = hugeCalc(i);
writeln( _hugeCalcCache.keys ); // this is some random
subset of (0,100)
but this does seem to work using your other method of
initialization :
auto _hugeCalcCache = new double[][](100);
foreach(i ; parallel(I))
_hugeCalcCache[i] = hugeCalc(i);
foreach( double[] x ; _hugeCalcCache)
writeln( x ); // this now contains all values
so I guess initializing the whole array at compile time makes it
thread safe ?
(The second case runs in 16 seconds on my computer.)
Anyways it seems to work, thanks again !
More information about the Digitalmars-d-learn
mailing list