in reply to Re^3: Refactoring: Better Variable Names For Better Understanding? [SOLVED]
in thread Refactoring: Better Variable Names For Better Understanding? [SOLVED]

You left out, " and perlmonks". I did not want to leave anybody out. There were other monks who answered this thread. I searched for the bits on BrowserUk suggesting drawing by line and flip. Very interesting and cool.

I came to realization as well. The motivation came from wanting the writer to do as little work as possible so to keep up with many workers. In fact, the bottom half is drawn using just 3 GD calls, copy upper half/flip vertically/copy into bottom half. Also, am drawing lines and setting pixels, not just lines.

Thank you for introducing us to Mandel and particularly creating the Threads From Hell #3 and series. Thank you BrowserUk. Thank you all. The original code does not mention the author's name unfortunately. The two eval statements are not necessary and wanting to let the author know.

Kind regards, Mario

  • Comment on Re^4: Refactoring: Better Variable Names For Better Understanding? [SOLVED]

Replies are listed 'Best First'.
Re^5: Refactoring: Better Variable Names For Better Understanding? [SOLVED]
by marioroy (Prior) on Jun 07, 2015 at 20:04 UTC

    Update: Finalized code, small changes.

    Update: Added MCE + Inline::C example.

    Solutions allowing one to run with or without threads for comparing against the shootout demonstration. The fastest time posted at the Computer Language Benchmarks site is 19.77 seconds. Perl + MCE + Inline::C runs 10 times faster.

    Testing was done on a Core i7 (Haswell 4 Cores with HT at 2.6 GHz / 1600 MHz memory).

    $ time perl mandelbrot1.pl 16000 > m1.pbm real 8m38.383s ( Perl code by Mykola Zubach, threads only ) $ time perl mandelbrot2.pl 16000 > m2.pbm real 3m52.245s ( MCE supporting threads and processes ) $ time perl mandelbrot3.pl 16000 > m3.pbm real 1.974s ( MCE + Inline::C, mind boggling )

    # http://benchmarksgame.alioth.debian.org/u64q/performance.php?test=ma +ndelbrot # based on Perl code contributed by Mykola Zubach # parallelization via MCE by Mario Roy use strict; use warnings; use MCE::Flow; use constant MAXITER => 50; use constant LIMIT => 4.0; use constant XMIN => -1.5; use constant YMIN => -1.0; use constant WHITE => "\000"; use constant BLACK => "\001"; my ( $w, $h, $m, $invN ); sub draw_line { my ( $mce, $y, $chunk_id ) = @_; my ( $Cr, $Zr, $Zi, $Tr, $Ti ); my $Ci = $y * $invN + YMIN; my $line; LOOP: for my $x (0 .. $w - 1) { $Cr = $x * $invN + XMIN; $Zr = $Zi = $Tr = $Ti = 0.0; for (1 .. MAXITER) { $Zi = $Zi * 2 * $Zr + $Ci; $Zr = $Tr - $Ti + $Cr; $Ti = $Zi * $Zi; $Tr = $Zr * $Zr; if ($Tr + $Ti > LIMIT) { $line .= WHITE; next LOOP; } } $line .= BLACK; } MCE->gather( $chunk_id, pack('B*', $line) ); } ## MAIN() $w = $h = shift || 200; $m = int( $h / 2 ); $invN = 2 / $w; # Compute upper-half only, gather lines my %picture = mce_flow_s { chunk_size => 1 }, \&draw_line, 0, $m; # Output PBM image header # Output upper half # Remove first and last lines # Output bottom half in reverse binmode STDOUT; print "P4\n$w $h\n"; print @picture{ sort { $a <=> $b } keys %picture }; delete @picture{ 1, $m + 1 }; print @picture{ sort { $b <=> $a } keys %picture };

    Below, code using MCE + Inline::C for extra performance.

    # http://benchmarksgame.alioth.debian.org/u64q/performance.php?test=ma +ndelbrot # based on Perl code contributed by Mykola Zubach # parallelization via MCE + Inline::C by Mario Roy use strict; use warnings; use MCE::Flow; use Inline 'C' => Config => CCFLAGSEX => '-O2'; use Inline 'C' => <<'END_C'; #define MAXITER 50 #define LIMIT 4.0 #define XMIN -1.5 #define YMIN -1.0 #define WHITE "\000" #define BLACK "\001" int width; double invN; void c_init( int _width, double _invN ) { width = _width; invN = _invN; } SV* c_draw_line( int y ) { SV *line = newSVpvn( "", 0 ); double Ci, Cr, Zr, Zi, Tr, Ti; int x, j; Ci = (double) y * invN + YMIN; x = -1; LOOP: do { if ( ++x >= width ) break; Cr = (double) x * invN + XMIN; Zr = Zi = Tr = Ti = 0.0; for (j = 1; j <= MAXITER; j++) { Zi = Zi * 2.0 * Zr + Ci; Zr = Tr - Ti + Cr; Ti = Zi * Zi; Tr = Zr * Zr; if (Tr + Ti > LIMIT) { sv_catpvn( line, WHITE, 1 ); goto LOOP; } } sv_catpvn( line, BLACK, 1 ); } while ( 1 ); return sv_2mortal( line ); } END_C my ( $w, $h, $m, $invN ); sub draw_line { my ( $mce, $y, $chunk_id ) = @_; my $line = c_draw_line( $y ); MCE->gather( $chunk_id, pack('B*', $line) ); } ## MAIN() $w = $h = shift || 200; $m = int( $h / 2 ); $invN = 2 / $w; # Init C c_init( $w, $invN ); # Compute upper-half only, gather lines my %picture = mce_flow_s { chunk_size => 1 }, \&draw_line, 0, $m; # Output PBM image header # Output upper half # Remove first and last lines # Output bottom half in reverse binmode STDOUT; print "P4\n$w $h\n"; print @picture{ sort { $a <=> $b } keys %picture }; delete @picture{ 1, $m + 1 }; print @picture{ sort { $b <=> $a } keys %picture };
Re^5: Refactoring: Better Variable Names For Better Understanding? [SOLVED]
by karlgoethebier (Abbot) on Jun 07, 2015 at 15:39 UTC
    "You left out, ' and perlmonks'"

    Yes, but just because i can't answer for the other bros that contributed :-)

    "The original code does not mention the author's name unfortunately"

    I tried to figure out too who he is, with no success yet.

    "...I did not want to leave anybody out..."

    I know. I just didn't want to claim the merits for me. I only asked a question. And i got superior answers. Stuff for month to work through. Very nice.

    Best regards, Karl

    «The Crux of the Biscuit is the Apostrophe»