Update: Corrected a couple 1 off errors.

Update: Computes the upper half only. Makes a copy afterwards, flips vertically, and copies into bottom half.

Update: Draw lines when possible.

The following is constructed using MCE::Flow with 2 tasks (many providers and one writer). Spawning workers early is not necessary for this demonstration. I went with GD due to running faster than Imager. However, one can easily change to Imager inside the writer function.

use strict; use warnings; use MCE::Flow Sereal => 1; use MCE::Queue Fast => 1; use GD; # based on original code at http://www.alfrog.com/mandel.html # karlgoethebier: initial code refactor, thanks perlmonks # marioroy: parallelization via MCE::Flow (2 user tasks) # process upper half only (reduces work for writer by 50%) # draw lines when possible (reduces work for writer by 56x) # also see tips by BrowserUk at: # http://www.perlmonks.org/?node_id=1128885 # fasten your seat belt, enjoy the ride :) my $width = 1280 * 1; my $height = 1024 * 1; my $iterations = 20; my $Q = MCE::Queue->new(); my $num_mandels = 3; my $num_writers = 1; # must be 1 # init MCE MCE::Flow::init { bounds_only => 1, chunk_size => 16, max_workers => [ $num_mandels, $num_writers ], task_name => [ 'tsk_mandel', 'tsk_writer' ], user_end => sub { my ( $mce, $task_id, $task_name ) = @_; $Q->enqueue(undef) if ( $task_name eq 'tsk_mandel' ); } }; # compute mandelbrot (user tasks; sequence begin, end ) MCE::Flow::run_seq( \&mandel, \&writer, 0, $width - 1 ); MCE::Flow::finish; # for MCE providers sub mandel { my ( $mce, $chunk_ref, $chunk_id ) = @_; my ( $re_c, $im_c, $re_z, $im_z, $color, $last_color, $temp ); my ( @ret, $middle ); $middle = int( $height / 2 ); for my $x ( $chunk_ref->[0] .. $chunk_ref->[1] ) { for my $y ( 0 .. $middle ) { $re_c = ( $x - 3 * $width / 4 ) / ( $width / 3 ); $im_c = ( $y - $height / 2 ) / ( $width / 3 ); $re_z = $im_z = $color = 0; while ( 1 ) { $temp = $re_z; $re_z = $re_z * $re_z - $im_z * $im_z + $re_c; $im_z = 2 * $temp * $im_z + $im_c; ++$color; last if $re_z * $re_z + $im_z * $im_z > 4; if ( $color == $iterations ) { $color = 0; last; } } if ( $y && $color == $last_color ) { # increment line size, writer draws a line when > 0 $ret[-1]++; } else { push @ret, $x, $y, $color, 0; $last_color = $color; } } } # freezing here to prevent double freezing/thawing $Q->enqueue( MCE->freeze( \@ret ) ); } # for MCE consumer sub writer { my ( $mce ) = @_; # init image and color palette my $image = new GD::Image( $width, $height ); my @palette = $image->colorAllocate( 0, 0, 0 ); # black for ( 1 .. $iterations ) { my ( $r, $g, $b ) = map { int rand 255 } 1 .. 3; push @palette, $image->colorAllocate( $r, $g, $b ); } # process draw requests while (1) { my $ret = $Q->dequeue; if (!defined $ret) { last unless --$num_mandels; next; } my $data = MCE->thaw( $ret ); my $size = @{ $data }; for ( my $i = 0; $i < $size; $i += 4 ) { if ( $data->[$i+3] ) { # draw line if line_size > 0 $image->line( $data->[$i], # x1 $data->[$i+1], # y1 $data->[$i], # x2 $data->[$i+1] + $data->[$i+3], # y2 $palette[ $data->[$i+2] ] # color ); } else { # otherwise, set pixel $image->setPixel( $data->[$i], # x $data->[$i+1], # y $palette[ $data->[$i+2] ] # color ); } } } # copy upper half, flip vertically, then copy into bottom half my $middle = int( $height / 2 ); my $temp = new GD::Image( $width, $middle ); $temp->copy( $image, 0, 0, 0, 0, $width, $middle ); $temp->flipVertical(); $image->copy( $temp, 0, $middle + 1, 0, 0, $width, $middle ); # save image open my $fh, '>mandelbrot.png' || return 1; binmode $fh; print $fh $image->png; close $fh; }

The examples demonstrate using the Core MCE API and MCE::Flow.


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

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.