Hi, vr
Tonight came across your post and modified your demonstration to run with 4 threads.
# https://www.perlmonks.org/?node_id=1214227
use strict;
use warnings;
use feature 'say';
use PDL;
use PDL::Parallel::threads qw(retrieve_pdls);
use threads;
use MCE::Shared;
use Time::HiRes 'time';
srand( 123 );
my $time = time;
my $n = 30000; # input sample size
my $m = 10000; # number of bootstrap repeats
my $r = $n; # re-sample size
my $x = random( $n ); $x->share_as('x');
my $avg = zeroes( $m ); $avg->share_as('avg');
my $seq = MCE::Shared->sequence( 0, $m - 1 );
sub parallel_task {
srand;
my ( $x, $avg ) = retrieve_pdls('x', 'avg');
while ( defined ( my $seq_n = $seq->next() ) ) {
my $idx = random $r;
$idx *= $n;
$avg->set( $seq_n, $x->index( $idx )->avg );
}
}
threads->create( \¶llel_task ) for 1 .. 4;
# ... do other stuff ...
$_->join() for threads->list();
say $avg->pctover( pdl 0.05, 0.95 );
say time - $time, ' seconds';
__END__
# Output
[0.49395242 0.49936752]
1.28744792938232 seconds
Afterwards, re-validated PDL with MCE and released 1.847. The effort is mainly for folks running Perl lacking threads support. Here it is, PDL and MCE::Shared running similarly.
# https://www.perlmonks.org/?node_id=1214227
use strict;
use warnings;
use feature 'say';
use PDL; # must load PDL before MCE::Shared
use MCE::Hobo;
use MCE::Shared 1.847;
use Time::HiRes 'time';
srand( 123 );
my $time = time;
my $n = 30000; # input sample size
my $m = 10000; # number of bootstrap repeats
my $r = $n; # re-sample size
# On Windows, the non-shared piddle ($x) is unblessed in threads.
# Therefore, constructing the piddle inside the worker.
# UNIX platforms benefit from copy-on-write. Thus, one copy.
my $x = ( $^O eq 'MSWin32' ) ? undef : random( $n );
my $avg = MCE::Shared->pdl_zeroes( $m );
my $seq = MCE::Shared->sequence( 0, $m - 1 );
sub parallel_task {
$x = random( $n ) unless ( defined $x );
while ( defined ( my $seq_n = $seq->next() ) ) {
my $idx = random $r;
$idx *= $n;
# $avg is a shared piddle which resides inside the shared-
# manager process or thread. The piddle is accessible via the
# OO interface only.
$avg->set( $seq_n, $x->index( $idx )->avg );
}
}
MCE::Hobo->create( \¶llel_task ) for 1 .. 4;
# ... do other stuff ...
MCE::Hobo->wait_all();
# MCE sets the seed of the base generator uniquely between workers.
# Unfortunately, it requires running with one worker for predictable
# results (i.e. no guarantee in the order which worker computes the
# next input chunk).
say $avg->pctover( pdl 0.05, 0.95 );
say time - $time, ' seconds';
__END__
# Output
[0.49387191 0.49937053]
1.29038286209106 seconds
Regards, Mario
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.