Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save marioroy/46fc4f4b87f57724cdde843607d060fe to your computer and use it in GitHub Desktop.
Save marioroy/46fc4f4b87f57724cdde843607d060fe to your computer and use it in GitHub Desktop.
#!/usr/bin/env perl
# Parallel demonstration for Recurring Monte Carlo Pi Calculation
# https://gist.github.com/dmr3/e69127ab449bdabd5af7b000c9b5b3b1
#
# Original source by Demian Riccardi, Joel Berger
# Parallel demonstration by Mario Roy
use Mojolicious::Lite;
use MCE::Loop 1.808;
use MCE::Shared;
my $cnt_pi = MCE::Shared->scalar(0);
MCE::Loop->init(
max_workers => 3,
chunk_size => 10000,
bounds_only => 1
);
# jump off from example by Joel Berger in Intro to Mojolicious
any '/' => 'index';
websocket '/data' => sub {
my $self = shift;
my ($pi,$runs,$new_runs) = (0,0,1000000);
my $timer = Mojo::IOLoop->recurring( 0.1 => sub {
($pi,$runs) = calc_pi($pi,$runs,$new_runs);
$self->send({ json => [$runs,$pi] });
});
$self->on( finish => sub {
Mojo::IOLoop->remove($timer);
MCE::Loop->finish;
});
};
sub gen_data {
my $x = shift;
return [ $x, sin( $x + 2*rand() - 2*rand() ) ]
}
sub worker_task {
my ($mce, $seq, $chunk_id) = @_;
my ($cnt, $x, $y) = (0);
foreach ( $seq->[0] .. $seq->[1] ) {
$x = rand(1);
$y = rand(1);
$cnt++ if $x * $x + $y * $y > 1;
}
$cnt_pi->incrby($cnt);
}
sub calc_pi {
my ( $pi, $total_runs, $new_runs ) = @_;
# use the itr to show how to submit multiples
$cnt_pi->set( -1 * ( ( $pi * $total_runs ) / 4 - $total_runs ) );
# MCE workers persist between runs
MCE::Loop->run_seq( \&worker_task, 1, $new_runs );
$total_runs += $new_runs;
$pi = 4 * ( $total_runs - $cnt_pi->get ) / $total_runs;
return ($pi, $total_runs);
}
app->start;
__DATA__
@@ index.html.ep
<!DOCTYPE html>
<html>
<head>
<title><%= title %></title>
</head>
<body>
%= content
</body>
<html>
%= javascript 'https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js'
%= javascript 'https://cdnjs.cloudflare.com/ajax/libs/flot/0.8.3/jquery.flot.js'
<div id="plot" style="width:600px;height:300px">
</div>
%= javascript begin
var data = [];
var plot = $.plot($('#plot'), [ data ]);
var url = '<%= url_for('data')->to_abs %>';
var ws = new WebSocket( url );
ws.onmessage = function(e){
var point = JSON.parse(e.data);
data.push(point);
plot.setData([data]);
plot.setupGrid();
plot.draw();
};
% end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment