Seems the issue has more to do with running an empty loop, rather than
performing a real computation.

This is a run on a 4-core box. Attempting to parallelize an empty loop makes
the execution 1 second slower:

    my &code = { for ^2_000_000 { } };

    my $start = now; (^4).map: &code; my $stop = now;
    say "Serial: {$stop - $start}";

    $start = now; await (^4).map: {start code}; $stop = now;
    say "Parallel: {$stop - $start}";

    # Serial: 1.5161628
    # Parallel: 2.56597794


But running actual real-life code makes it almost 4 times faster, as 
would be expected on a 4-core box:

    use Crypt::Bcrypt;
    my &code = { bcrypt-hash ~rand, :15rounds; };

    my $start = now; (^4).map: &code; my $stop = now;
    say "Serial: {$stop - $start}";

    $start = now; await (^4).map: {start code}; $stop = now;
    say "Parallel: {$stop - $start}";

    # Serial: 7.69045687
    # Parallel: 2.087147






On Sat Oct 01 06:15:18 2016, steve.pi...@gmail.com wrote:
> This could be a stupid user problem, in which case I apologise for wasting  
> your time.
> 
> Simple concurrency demonstrations seem to work; the following completes in  
> just over a second:
> 
> perl6 -e 'await Promise.allof(start {sleep 1}, start {sleep 1}, start  
> {sleep 1});say now - INIT now'
> 
> However if the started tasks are doing any CPU-intensive work, they seem  
> to take much longer than if they had been run sequentially, without using  
> promises at all.
> 
> To reproduce the issue, please run this script.
> 
> -----
> use v6;
> 
> my $r = 2_000_000;
> 
> say "Counting to $r";
> 
> my ($start, $setup, $stop);
> $start = now;
> {
>      my ($i, $j);
>      $j = $r;
>      loop ($i = 0; $i < $j; $i++) { }
> }
> $stop = now;
> 
> say "Non-promise iteration: {$stop - $start}";
> 
> my @promises;
> $start = now;
> @promises.push(start {
>      my ($i, $j);
>      $j = $r;
>      loop ($i = 0; $i < $j; $i++) { }
> });
> $setup = now;
> await Promise.allof(@promises);
> $stop = now;
> 
> say "One iteration: {$stop - $start} (setup: {$setup - $start})";
> 
> @promises = ();
> 
> $start = now;
> for (1..16) {
>      @promises.push(start {
>          my ($i, $j);
>          $j = $r;
>          loop ($i = 0; $i < $j; $i++) { }
>      });
> }
> $setup = now;
> await Promise.allof(@promises);
> $stop = now;
> 
> say "16 iterations: {$stop - $start} (setup: {$setup - $start})";
> -----
> 
> What I expected:
> 
> One iteration would take roughly the same amount of time as the  
> non-promise iteration (the sleep example above would suggest that the  
> threading overhead would be less than 0.001s)
> 
> 16 iterations would take, at worst, about 16 times as long as the line  
> 'one iteration' above it.
> 
> What happens:
> 
> On a Windows 10 PC, with 6 cores (12 logical processors)
> 
> C:\Users\Steve>perl6 concurrency-wtf.pl
> Counting to 2000000
> Non-promise iteration: 0.6162481
> One iteration: 2.23909643 (setup: 0.00300325)
> 16 iterations: 65.56993665 (setup: 0.00700654)
> 
> On an Ubuntu 14.04.5 LTS PC, with 2 cores
> 
> steve@prole:~/$ perl6 concurrency-wtf.pl
> Counting to 2000000
> Non-promise iteration: 0.6948201
> One iteration: 1.9678549 (setup: 0.0024696)
> 16 iterations: 107.1483633 (setup: 0.0474610)
> 
> Also the CPU usage leaps 100% (all CPUs, all at 100%) while running, on  
> both PCs. The PCs are mostly idle otherwise (Windows 10 - about 3%  
> utilization, Linux - 199% idle)
> 
> Perl 6 version
> 
> C:\Users\Steve>perl6 -v
> This is Rakudo version 2016.07.1 built on MoarVM version 2016.07
> implementing Perl 6.c.
> 
> steve@prole:~/$ perl6 -v
> This is Rakudo version 2016.07.1 built on MoarVM version 2016.07
> implementing Perl 6.c.



Reply via email to