Indeed, but the final death knell is that using a mirror structure of individual sems is 3 times slower than locking the entire hash!
Lock the hash:
#! perl -slw use strict; use Data::Dump qw[ pp ]; use Time::HiRes qw[ time ]; use List::Util qw[ shuffle ]; use threads; use threads::shared; our $START //= 'aaa'; our $END //= 'zzz'; my %hash :shared = map{ $_ => 0 } $START .. $END; my $start = time; $_->join for map{ async{ my @order; { lock %hash; @order = shuffle keys %hash; } for ( @order ) { lock %hash; ++$hash{ $_ }; } } } 1 .. 4; printf "Lock hash took %.3f seconds\n", time() - $start; my @fails = grep $_ != 4, values %hash; warn @fails . " fails\n" if @fails; __END__ C:\test>909437-1 Lock hash took 1.093 seconds
Locking scalars:
#! perl -slw use strict; use Data::Dump qw[ pp ]; use Time::HiRes qw[ time ]; use List::Util qw[ shuffle ]; use threads; use threads::shared; our $START //= 'aaa'; our $END //= 'zzz'; my %sems :shared = map{ my $n :shared = 0; $_ => \$n } $START .. $END; my %hash :shared = map{ $_ => 0 } $START .. $END; my $start = time; $_->join for map{ async{ my @order; { lock %hash; @order = shuffle keys %hash; } for ( @order ) { lock ${ $sems{ $_ } }; ++$hash{ $_ }; } } } 1 .. 4; printf "Lock scalars ref took %.3f seconds\n", time() - $start; my @fails = grep $_ != 4, values %hash; warn @fails . " fails\n" if @fails; __END__ C:\test>909437-3 Lock scalars ref took 4.667 seconds
In reply to Re^8: Avoid Locking Entire Hashes
by BrowserUk
in thread Avoid Locking Entire Hashes
by jagan_1234
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |