use strict;
use warnings;
use ntheory 0.67 ":all";
use MCE::Flow 1.831;
use MCE::Shared;
mce_open my $err_fh, '>>', \*STDERR;
my ( $name, $rng );
my %rand = (
"drand48" => sub { int(rand(1 << 32)) },
"ChaCha20" => sub { irand64() },
"/dev/urandom" => sub { unpack("Q", random_bytes(8)) }
);
# Workers receive [ begin, end ] values.
MCE::Flow::init(
max_workers => MCE::Util::get_ncpu(),
chunk_size => 10000,
bounds_only => 1,
user_begin => sub {
$name = MCE->user_args()->[0];
$rng = $rand{ $name };
}
);
sub func {
my ( $beg_seq, $end_seq ) = @{ $_ };
my ( $t, $pairs, $r1, $r2 ) = ( 0, '' );
for ( $beg_seq .. $end_seq ) {
( $r1, $r2 ) = ( $rng->(), $rng->() );
if ( gcd($r1, $r2) == 1 ) {
$pairs .= sprintf("%20s %20s\n", $r1, $r2);
$t++;
}
}
print $err_fh $pairs;
MCE->gather($t);
}
# The user_args option is how to pass arguments.
sub cesaro {
my ( $name ) = @_;
print "Usage $name:\n";
my $n = 10 ** 5;
my @ret = mce_flow_s { user_args => [$name] }, \&func, 0, $n - 1;
my $t = 0; $t += $_ for @ret;
printf "%8d %0.8f\n", $n, sqrt(6 * $n / $t);
printf "%9s %s\n\n", "Pi", Pi();
}
cesaro("/dev/urandom");
####
Usage /dev/urandom:
100000 3.14168852
Pi 3.14159265358979
##
##
3287478503828099458 17020534165422626509
12874128583739175743 15858105624010204897
12114767169191945777 1381808520787800067
6217235583185614040 13880267056100467759
6095107227201871385 14484880859615821612
6023474899938562107 6188664627301334099
2843055836738994412 3086747352859159329
10461621510749606095 302140866635797242
11160050491040241465 8409335412227119072
3718439936437935345 5121716120103428116
...