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 !

Reply via email to