#!/usr/bin/perl -w use Term::ReadKey; my $count=14; my $chop=3; my $mode=''; if(defined $ARGV[0] && $ARGV[0] eq '-x') { shift @ARGV; $mode='xml'; } #(type, jvm options, xml attributes) my @options =( ['Normal - client','-XX:+CITime', 'inlining="Normal" mode="Client"'], ['GC (normal)','-XX:+CITime -verbosegc', 'inlining="Normal" mode="Client" gcstats="true"'], ['No inlining - client', '-XX:+CITime -XX:MaxInlineSize=0 -XX:FreqInlineSize=0', 'inlining="None" mode="Client"'], ['Interpreter','-Xint','mode="Interpreter"'], ['Normal - server','-XX:+CITime -server', 'inlining="Normal" mode="Server"'], ['No inlining - server', '-XX:+CITime -server -XX:MaxInlineSize=0 -XX:FreqInlineSize=0', 'inlining="None" mode="Server"'], ); $java = "$ENV{JAVA_HOME}/bin/java"; # get java version open NULL,qq{$java -version 2>&1 |}; while() { if(/^Java\(TM\).*\(build ([^)]+)\)/) { $javaver=$1; } } close NULL; # get hostname open NULL,qq{hostname|}; while() { if(/^([^\.]*).*$/) { $hostname=$1; } } chomp($hostname); close NULL; # get flavour open(FILE, "runtimeFlavour") or die("Error: Can't open runtimeFlavour"); chomp($flavour = ); close FILE; $name = shift(@ARGV); $script = "run.sh"; if($mode eq 'xml') { open XML,">results/timings.$hostname.$flavour.$javaver.xml"; print XML qq{ }; } foreach my $dets (@options) { my ($type,$options,$xmlattrs)=@$dets; my @times=(); print STDERR "$name ($type): "; ## ## Run benchmark, collect timing data ## ## while(scalar @times < $count) { my $key=ReadKey(-1); if(defined $key) { if(lc($key) eq 's') { last; } elsif(lc($key) eq 'q') { print "\n"; exit(-1); } } my $comptime; my $compbcs; my $gccount; my $gctime; if($type eq 'GC (normal)') { $gccount=0; $gctime=0; } open NULL,qq{/usr/bin/time -o timings.tmp -f "%S %U %e" ./$script $options 2>&1 |}; while() { if(/^\s+Total compilation time\s+:\s+(\d+\.\d+) s/) { $comptime=$1; } if(/^\s+Total compiled bytecodes\s+:\s+(\d+) bytes/) { $compbcs=$1; } if(/^\[(?:Full\s)?GC .*\,\s(\d\.\d+)\ssecs/) { $gccount++; $gctime+=$1; } } close NULL; if(!defined $comptime || !defined $compbcs) { warn "Didn't get JIT details" unless $type eq 'Interpreter'; } if(!defined $gccount || !defined $gctime) { warn "Didn't get GC details" if $type eq 'GC (normal)'; } open TIME,") { chomp; if(my($sys,$user,$elapsed)=/^(\d+\.\d\d) (\d+\.\d\d) (\d+\.\d\d)/) { my $total=$sys+$user; my $ratio=$total/$elapsed; # print "Total $total Elapsed $elapsed Ratio $ratio\n"; # if(0.99*$elapsed-0.05<=$total && $total<=1.01*$elapsed+0.05) { push @times,{'elapsed' => $elapsed, 'jittime' => $comptime, 'jitbcs' => $compbcs, 'gccount' => $gccount, 'gctime' => $gctime}; print STDERR 'o'; # } else { # print STDERR '.'; # } } else { warn "Couldn't parse $_"; } } close TIME; unlink "timings.tmp"; } print STDERR "\n"; ## ## Process timing data ## ## # print join(',',@times)."\n"; my @sorted=sort {$a->{'elapsed'} <=> $b->{'elapsed'}} @times; # print join(',',@sorted)."\n"; my $sum=0; my $jittime=0; my $jitbcs=0; my $totgccount=0; my $totgctime=0; # drop $chop smallest and largest runtimes foreach my $i ($chop..($count-$chop-1)) { $sum+=$sorted[$i]->{'elapsed'}; if($type ne 'Interpreter') { $jittime+=$sorted[$i]->{'jittime'}; $jitbcs+=$sorted[$i]->{'jitbcs'}; } if($type eq 'GC (normal)') { $totgccount+=$sorted[$i]->{'gccount'}; $totgctime+=$sorted[$i]->{'gctime'}; } } my $avg=$sum/($count-2*$chop); if($type ne 'Interpreter') { $jittime=$jittime/($count-2*$chop); $jitbcs=$jitbcs/($count-2*$chop); } if($type eq 'GC (normal)') { $totgccount=$totgccount/($count-2*$chop); $totgctime=$totgctime/($count-2*$chop); } my $sum_sd = 0; my $jittime_sd = 0; my $jitbcs_sd = 0; my $totgccount_sd = 0; my $totgctime_sd = 0; foreach my $i ($chop..($count-$chop-1)) { $sum_sd = ($sorted[$i]->{'elapsed'} - $avg) ** 2; if($type ne 'Interpreter') { $jittime_sd = ($sorted[$i]->{'jittime'} - $jittime) ** 2; $jitbcs_sd = ($sorted[$i]->{'jitbcs'} - $jitbcs) ** 2; } if($type eq 'GC (normal)') { $totgccount_sd = ($sorted[$i]->{'totgccount'} - $totgccount) ** 2; $totgctime_sd = ($sorted[$i]->{'totgctime'} - $totgctime) ** 2; } } $sum_sd = sqrt($sum_sd / ($count - 2*$chop)); if($type ne 'Interpreter') { $jittime_sd = sqrt($jittime_sd / ($count - 2*$chop)); $jitbcs_sd = sqrt($jitbcs_sd / ($count - 2*$chop)); } if($type eq 'GC (normal)') { $totgccount_sd = sqrt($totgccount_sd / ($count - 2*$chop)); $totgctime_sd = sqrt($totgctime_sd / ($count - 2*$chop)); } if($mode eq 'xml') { print XML " \n"; print XML " \n"; print XML " " .$sorted[$chop-1]->{'elapsed'}."\n"; print XML " " .$sorted[$count-$chop]->{'elapsed'}."\n"; if ($type ne 'Interpreter') { print XML " " .$jittime."$jittime_sd\n"; print XML " " .$jitbcs."$jitbcs_sd\n"; } if($type eq 'GC (normal)') { print XML " $totgccount" ."$totgccount_sd\n"; print XML " $totgctime" ."$totgctime_sd\n"; } print XML " \n"; } print "$name ($type): $avg "; print "JIT time $jittime bytecodes $jitbcs " unless $type eq 'Interpreter'; print "GC count $totgccount time $totgctime " if $type eq 'GC (normal)'; print "(chopped times: $sorted[$chop-1]->{'elapsed'}, " ."$sorted[$count-$chop]->{'elapsed'})\n"; } if ($mode eq 'xml') { print XML qq{ }; close XML; } print "\n";