On Tue, 04 Oct 2016 04:23:54 +1300, Joachim Durchholz via RT <perl6-bugs-follo...@perl.org> wrote:

Am 03.10.2016 um 06:34 schrieb Zoffix Znet via RT:
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:

[...]

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

(Disclaimer: I have no ideas of the internals, but I know a bit about
concurrency.)

This might be four cores competing to get update access to the loop counter.
Core-to-core synchronization of a memory cell with high-frequency
updates is an extremely expensive operation, with dozens or hundreds of
wait states to request exclusive cache lines access and to move the
current state of the variable from one CPU's cache to the next.

For what it's worth, I've tried this with 4 separate functions, one per thread. That should - to my mind - hopefully avoid blocking on cache line access.

It doesn't seem to make a noticeable difference to performance.

The comment below is the output of the following program, compared to the times listed for the Fibonacci program elsewhere in this issue. Replacing @fibs with @fibs = &fib1 xx 4 results in closer times.

# No thread: 12.6327946  (vs 13.0872902)
# Parallel: 20.6087147   (vs 21.01963220)
# Single: 15.4441904     (vs 15.47348977)
# No thread: 15.4208225

use v6;

sub fib1($n) {
    $n < 2 ?? $n !! fib1($n - 1) + fib1($n - 2);
}

sub fib2($n) {
    $n < 2 ?? $n !! fib2($n - 1) + fib2($n - 2);
}

sub fib3($n) {
    $n < 2 ?? $n !! fib3($n - 1) + fib3($n - 2);
}

sub fib4($n) {
    $n < 2 ?? $n !! fib4($n - 1) + fib4($n - 2);
}

my @fibs = &fib1, &fib2, &fib3, &fib4;

constant FIB = 30;

my ($start, $stop);

$start = now;
(^4).map: { @fibs[$^a](FIB) };
$stop = now;
say "No thread: {$stop - $start}";

$start = now;
await (^4).map: { start @fibs[$^a](FIB) };
$stop = now;
say "Parallel: {$stop - $start}";

$start = now;
await start { (^4).map: { @fibs[$^a](FIB) } };
$stop = now;
say "Single: {$stop - $start}";

$start = now;
(^4).map: { @fibs[$^a](FIB) };
$stop = now;
say "No thread: {$stop - $start}";

Reply via email to