use strict;
use warnings;
use MCE::Flow;
my $N;
# Workers receive [ begin, end ] values.
MCE::Flow::init(
max_workers => MCE::Util::get_ncpu(),
chunk_size => 100000,
bounds_only => 1,
user_begin => sub { $N = MCE->user_args()->[0] }
);
sub func {
my ( $beg_seq, $end_seq ) = @{ $_ };
my ( $pi, $t ) = ( 0.0 );
for my $i ( $beg_seq .. $end_seq ) {
$t = ( $i + 0.5 ) / $N;
$pi += 4.0 / ( 1.0 + $t * $t );
}
MCE->gather($pi);
}
# The user_args option is how to pass arguments.
# Workers persist between each run.
for my $e ( 1..8 ) {
my $n = 10 ** $e;
my @ret = mce_flow_s { user_args => [$n] }, \&func, 0, $n - 1;
my $pi = 0.0; $pi += $_ for @ret;
printf "%9d %0.14f\n", $n, $pi / $n;
}
####
10 3.14242598500110
100 3.14160098692313
1000 3.14159273692312
10000 3.14159265442313
100000 3.14159265359816
1000000 3.14159265358988
10000000 3.14159265358979
100000000 3.14159265358979
####
use strict;
use warnings;
use Inline 'C' => <<'END_C';
unsigned int N = 0;
void c_init( unsigned int n )
{
N = n;
}
double c_func( unsigned int beg_seq, unsigned int end_seq )
{
double t, pi = 0.0;
unsigned int i;
for ( i = beg_seq ; i <= end_seq ; i++ ) {
t = (double) i / (double) N;
pi += 4.0 / ( 1.0 + t * t );
}
return pi;
}
END_C
use MCE::Flow;
# Workers receive [ begin, end ] values.
MCE::Flow::init(
max_workers => MCE::Util::get_ncpu(),
chunk_size => 100000,
bounds_only => 1,
user_begin => sub { c_init( MCE->user_args()->[0] ) }
);
sub func {
my ( $beg_seq, $end_seq ) = @{ $_ };
my $pi = c_func($beg_seq, $end_seq);
MCE->gather($pi);
}
# The user_args option is how to pass arguments.
# Workers persist between each run.
for my $e ( 1..8 ) {
my $n = 10 ** $e;
my @ret = mce_flow_s { user_args => [$n] }, \&func, 0, $n - 1;
my $pi = 0.0; $pi += $_ for @ret;
printf "%9d %0.14f\n", $n, $pi / $n;
}
####
10 3.23992598890716
100 3.15157598692313
1000 3.14259248692312
10000 3.14169265192314
100000 3.14160265357315
1000000 3.14159365358964
10000000 3.14159275358979
100000000 3.14159266358980