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