On Friday, 1 September 2017 at 04:43:29 UTC, Ali Çehreli wrote:
On 08/31/2017 06:59 PM, Brian wrote:
> Hello, I am trying to get the most trivial example of
multithreading
> working, but can't seem to figure it out.
> I want to split a task across threads, and wait for all those
tasks to
> finish before moving to the next line of code.
>
> The following 2 attempts have failed :
>
> -----------------------------------------------------
> Trial 1 :
> -----------------------------------------------------
>
> auto I = std.range.iota(0,500);
> int [] X; // output
> foreach (i; parallel(I) )
>     X ~= i;
> core.thread.thread_joinAll(); // Apparently no applicable
here ?

As Michael Coulombe said, parallel() does that implicitly.

If the problem is to generate numbers in parallel, I restructured the code by letting each thread touch only its element of a results array that has already been resized for all the results (so that there is no race condition):

import std.stdio;
import std.parallelism;
import std.range;

void main() {
    auto arrs = new int[][](totalCPUs);
    const perWorker = 10;
    foreach (i, arr; parallel(arrs)) {
        const beg = cast(int)i * perWorker;
        const end = beg + perWorker;
        arrs[i] = std.range.iota(beg,end).array;
    }

    writeln(arrs);
}

If needed, std.algorithm.joiner can be used to make it a single sequence of ints:

    import std.algorithm;
    writeln(arrs.joiner);

Ali

Hello, thank you very much for your quick replies !

I was trying to make a trivial example, but the 'real' problem is trying to split a huge calculation to different threads.

Schematically :

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.

Very interesting approach about letting only the thread touch a particular element, I will try that.

FYI I did manage to make the following work, but not sure if this is really still multi-threaded ?


        int [] I;
        foreach (i; 0 .. 500) I ~= i;
        int [] X; // output
        class DerivedThread : Thread {
                private int [] i;
                this(int [] i){
                        this.i = i;
                        super(&run);
                }
                private void run(){
                        synchronized{ // Need synchronization here !
                                foreach( i0; i)
                                        X ~= i0;
                        }
                }
        }
        Thread [] threads;
        foreach (i; std.range.chunks( I, 50 ) )
                threads ~= new DerivedThread( i);
        foreach( thread; threads)
                thread.start();
        
core.thread.thread_joinAll(); // Does in fact seem to 'join all' threads
        writeln(X);

Reply via email to