github.com/coyove/nj@v0.0.0-20221110084952-c7f8db1065c3/tests/bench/spec.pl (about) 1 # The Computer Language Benchmarks Game 2 # https://salsa.debian.org/benchmarksgame-team/benchmarksgame/ 3 # 4 # Contributed by Andrew Rodland 5 # modified by R. Jelinek 6 # multicore by Mykola Zubach 7 8 use strict; 9 use threads; 10 11 my $cpus = num_cpus(); 12 13 my $n = shift || 500; 14 my @v = multiplyAtAv( 15 multiplyAtAv( 16 multiplyAtAv((1) x $n) 17 ) 18 ); 19 20 my @u = multiplyAtAv(@v); 21 22 my ($vBv, $vv); 23 my $i = 0; 24 for my $v (@v) { 25 $vBv += $u[$i++] * $v; 26 $vv += $v ** 2; 27 } 28 29 printf "%0.9f\n", sqrt($vBv / $vv); 30 31 sub multiplyAtAv { 32 return multiplyAtv(multiplyAv(@_)); 33 } 34 35 sub eval_A { 36 use integer; 37 my $div = (($_[0] + $_[1]) * ($_[0] + $_[1] + 1) >> 1) + $_[0] + 1; 38 no integer; 39 1 / $div; 40 } 41 42 sub multiplyAv { 43 my($begin, $end, @threads); 44 my $chunk = int($#_ / $cpus) + 1; 45 46 for($begin = 0; $begin < $#_; $begin = $end + 1) { 47 $end = $begin + $chunk; 48 $end = $#_ if $end > $#_; 49 push @threads, threads->create( sub { 50 my $begin = shift; 51 my $end = shift; 52 return map { 53 my ($i, $sum) = ($_); 54 $sum += eval_A($i, $_) * $_[$_] for (0 .. $#_); 55 $sum; 56 } ($begin .. $end); 57 }, $begin, $end, @_); 58 } 59 return map $_->join, @threads; 60 } 61 62 sub multiplyAtv { 63 my($begin, $end, @threads); 64 my $chunk = int($#_ / $cpus) + 1; 65 66 for($begin = 0; $begin < $#_; $begin = $end + 1) { 67 $end = $begin + $chunk; 68 $end = $#_ if $end > $#_; 69 push @threads, threads->create( sub { 70 my $begin = shift; 71 my $end = shift; 72 return map { 73 my ($i, $sum) = ($_); 74 $sum += eval_A($_, $i) * $_[$_] for (0 .. $#_); 75 $sum; 76 } ($begin .. $end); 77 }, $begin, $end, @_); 78 } 79 return map $_->join, @threads; 80 } 81 82 sub num_cpus { 83 open my $fh, '</proc/cpuinfo' or return 4; 84 my $cpus; 85 while (<$fh>) { 86 $cpus ++ if /^processor\s+:/; 87 } 88 return $cpus; 89 }