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);