use strict; use warnings; use GD; use MCE::Loop; # based on original http://www.alfrog.com/mandel.html # karlgoethebier: code refactor # marioroy: parallelization my $width = 1280; my $height = 1024; my $image = new GD::Image( $width, $height ); my @palette = $image->colorAllocate( 0, 0, 0 ); # black my $iterations = 20; for ( 1 .. $iterations ) { my ( $r, $g, $b ) = map { int rand 255 } 1 .. 3; push @palette, $image->colorAllocate( $r, $g, $b ); } MCE::Loop::init { use_threads => 0, # Windows default to threads, not thread safe max_workers => 'auto', bounds_only => 1, gather => sub { my ( $x, $y, $color ); while ( ($x, $y, $color) = splice(@_, 0, 3) ) { $image->setPixel( $x, $y, $palette[ $color ] ) } } }; mce_loop_s { my ( $mce, $chunk_ref, $chunk_id ) = @_; my ( $re_c, $im_c, $re_z, $im_z, $color, $temp ); my ( @set_data ); for my $x ( $chunk_ref->[0] .. $chunk_ref->[1] ) { for my $y ( 0 .. $height - 1 ) { $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; } } push @set_data, $x, $y, $color; } } MCE->gather( @set_data ); } 0, $width - 1; MCE::Loop::finish; open my $fh, '>mandelbrot.png' || exit 1; binmode $fh; print $fh $image->png; close $fh;