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