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 ...