Jump to page: 1 2
Thread overview
parallel
Nov 05, 2015
Handyman
Nov 05, 2015
anonymous
Nov 05, 2015
Handyman
Nov 05, 2015
Ali Çehreli
Nov 05, 2015
Handyman
Nov 05, 2015
anonymous
Nov 05, 2015
Handyman
Nov 05, 2015
anonymous
Nov 05, 2015
Handyman
Nov 05, 2015
Ali Çehreli
Nov 05, 2015
Alex Parrill
November 05, 2015
import std.stdio;
import core.thread;
import std.datetime;          // for stopwatch
import std.parallelism;

void say(string s) {          // write and flush
   writeln(s);
   stdout.flush();
}

struct Dish {
   string name;
   void prepare() {
      say("Start with the " ~ name ~ ".");
      Thread.sleep(1.seconds); // kunstmatig tijd verbruiken
      say("Finished the " ~ name ~ ".");
   }
}

void main() {
   auto dishes = [ Dish("soup"), Dish("sauce"), Dish("fries"), Dish("fish"), Dish("ice") ];
   auto sw = StopWatch(AutoStart.yes);
   foreach (dish; parallel(dishes, 1)) dish.prepare();
   sw.stop;
   writefln("Diner is ready.  Cooking took %.3f seconds.", cast(float) sw.peek.msecs / 1000);
}

gives:

Start with the soup.
Start with the sauce.
Start with the fries.
Start with the fish.
Finished the sauce.
Finished the fries.
Start with the ice.
Finished the soup.
Finished the fish.
Finished the ice.
Diner is ready.  Cooking took 1.999 seconds.

Seems that 4 cores go all out on first 4 dishes, then 1 core deals with the last dish.  With 4 cores I expect diner is ready after 5/4 = 1.25 secs though.  What did I do wrong?
November 05, 2015
On 05.11.2015 21:30, Handyman wrote:
> Seems that 4 cores go all out on first 4 dishes, then 1 core deals with
> the last dish.  With 4 cores I expect diner is ready after 5/4 = 1.25
> secs though.  What did I do wrong?

You describe the situation correctly. The unit of work is a dish. That is, the work for a single dish is not split between cores. So one of your four cores has to make two dishes. That takes two seconds.
November 05, 2015
On Thursday, 5 November 2015 at 20:30:05 UTC, Handyman wrote:
> Seems that 4 cores go all out on first 4 dishes, then 1 core deals with the last dish.  With 4 cores I expect diner is ready after 5/4 = 1.25 secs though.  What did I do wrong?

The first four dishes get scheduled, all of them sleep for 1 second in parallel, then complete at roughly the same time. One second has passed.

Now there's one dish left. It gets scheduled, sleeps for 1 second, and finishes (the other threads remain idle). Two seconds have passed.
November 05, 2015
On Thursday, 5 November 2015 at 20:40:00 UTC, anonymous wrote:
> So one of your four cores has to make two dishes. That takes two seconds.

So make fine-grained?

foreach (i; 0..50)
   Thread.sleep(20.msecs);

But then my program still says: '2 secs'.   Please enlighten me.

November 05, 2015
On 11/05/2015 12:43 PM, Handyman wrote:
> On Thursday, 5 November 2015 at 20:40:00 UTC, anonymous wrote:
>> So one of your four cores has to make two dishes. That takes two seconds.
>
> So make fine-grained?
>
> foreach (i; 0..50)
>     Thread.sleep(20.msecs);
>
> But then my program still says: '2 secs'.   Please enlighten me.
>

That's still 1 second per task. The function prepare() cannot be executed by more than one core.

Ali

November 05, 2015
On Thursday, 5 November 2015 at 20:45:25 UTC, Ali Çehreli wrote:
> That's still 1 second per task. The function prepare() cannot be executed by more than one core.

Thanks.  OK.  So 'prepare' is atomic?  Then let's turn it around: how can I make the cores prepare a meal of 5 dishes in 1.25 secs?   Should I rewrite, or split, 'prepare'?


November 05, 2015
On 05.11.2015 21:43, Handyman wrote:
> foreach (i; 0..50)
>     Thread.sleep(20.msecs);
>
> But then my program still says: '2 secs'.   Please enlighten me.

Let's look at the line that does the `parallel` call:

    foreach (dish; parallel(dishes, 1)) dish.prepare();

This means that `dishes` is processed in parallel. Multiple threads are started to execute `prepare()` on multiple elements of `dishes` at the same time.

Each of those `dish.prepare()` calls is done on only one thread, though. There is not attempt to split the `prepare` action up and run parts of it in parallel.
November 05, 2015
On Thursday, 5 November 2015 at 20:54:37 UTC, anonymous wrote:
> There is not attempt to split the `prepare` action up and run parts of it in parallel.

So 1.25 secs is impossible?
November 05, 2015
On 05.11.2015 21:52, Handyman wrote:
> On Thursday, 5 November 2015 at 20:45:25 UTC, Ali Çehreli wrote:
>> That's still 1 second per task. The function prepare() cannot be
>> executed by more than one core.
>
> Thanks.  OK.  So 'prepare' is atomic?  Then let's turn it around: how
> can I make the cores prepare a meal of 5 dishes in 1.25 secs?   Should I
> rewrite, or split, 'prepare'?
>
>

You'd have to split `prepare` further into parallelizable parts. In a real world scenario that may or may not be possible.

When the goal is just sleeping we can do it, of course. Just do another `parallel` loop in `prepare`:

    import std.range: iota;
    foreach (i; parallel(iota(50))) Thread.sleep(20.msecs);

This won't get you down to exactly 1.25 seconds, because the start/finish print outs still take some time, and because of parallelization overhead.
November 05, 2015
On Thursday, 5 November 2015 at 21:10:16 UTC, anonymous wrote:
> parallel(iota(50)))

Wow. I have dealt with ranges and 'iota' (and with parallel), but I admit I have to think hard about this example.  Thanks a bunch all for your patience.

« First   ‹ Prev
1 2