digitalmars.D.learn - parallel
- Handyman (40/40) Nov 05 2015 import std.stdio;
- anonymous (4/7) Nov 05 2015 You describe the situation correctly. The unit of work is a dish. That
- Handyman (5/7) Nov 05 2015 So make fine-grained?
- =?UTF-8?Q?Ali_=c3=87ehreli?= (4/10) Nov 05 2015 That's still 1 second per task. The function prepare() cannot be
- Handyman (4/6) Nov 05 2015 Thanks. OK. So 'prepare' is atomic? Then let's turn it around:
- anonymous (9/12) Nov 05 2015 Let's look at the line that does the `parallel` call:
- Handyman (2/4) Nov 05 2015 So 1.25 secs is impossible?
- =?UTF-8?Q?Ali_=c3=87ehreli?= (5/9) Nov 05 2015 For the given example, yes, impossible. However, as mentioned elsewhere
- Alex Parrill (7/10) Nov 05 2015 The first four dishes get scheduled, all of them sleep for 1
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?
Nov 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.
Nov 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.
Nov 05 2015
On 11/05/2015 12:43 PM, Handyman wrote:On Thursday, 5 November 2015 at 20:40:00 UTC, anonymous wrote:That's still 1 second per task. The function prepare() cannot be executed by more than one core. AliSo 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.
Nov 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'?
Nov 05 2015
On 05.11.2015 21:52, Handyman wrote:On Thursday, 5 November 2015 at 20:45:25 UTC, Ali Çehreli wrote: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.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'?
Nov 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.
Nov 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.
Nov 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?
Nov 05 2015
On 11/05/2015 12:58 PM, Handyman wrote:On Thursday, 5 November 2015 at 20:54:37 UTC, anonymous wrote:For the given example, yes, impossible. However, as mentioned elsewhere in this thread, if prepare() is parallelizable itself, then it would be possible. AliThere is not attempt to split the `prepare` action up and run parts of it in parallel.So 1.25 secs is impossible?
Nov 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.
Nov 05 2015