Path: blob/master/runtime/compiler/tools/avgCompTime.pl
6000 views
##############################################################################1# Copyright (c) 2019, 2019 IBM Corp. and others2#3# This program and the accompanying materials are made available under4# the terms of the Eclipse Public License 2.0 which accompanies this5# distribution and is available at https://www.eclipse.org/legal/epl-2.0/6# or the Apache License, Version 2.0 which accompanies this distribution and7# is available at https://www.apache.org/licenses/LICENSE-2.0.8#9# This Source Code may also be made available under the following10# Secondary Licenses when the conditions for such availability set11# forth in the Eclipse Public License, v. 2.0 are satisfied: GNU12# General Public License, version 2 with the GNU Classpath13# Exception [1] and GNU General Public License, version 2 with the14# OpenJDK Assembly Exception [2].15#16# [1] https://www.gnu.org/software/classpath/license.html17# [2] http://openjdk.java.net/legal/assembly-exception.html18#19# SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception20##############################################################################2122#script to compute the average compilation time for methods in the vlog2324use strict;25use File::Find;2627my $compTimeThreshold = 1000000; # 100 ms2829if (@ARGV < 1) {30die "must provide at least one parameter: vlog_file\n";31}323334# hash of methods; each entry is an array of lines containing all occurrences of that method in the vlog35my %methodHash;363738# process each file given as argument39my $totalCompTime = 0;40foreach (map { glob } @ARGV) {41my $compTime = processVlog($_);42$totalCompTime += $compTime/1000; # convert to ms43}44print "total compilation time = $totalCompTime ms\n";4546474849sub UpdateStats {50$_[1] += 1; # update samples51$_[2] += $_[0]; # update totalTime52if ($_[0] > $_[3]) { #update MAX53$_[3] = $_[0];54}55if ($_[0] < $_[4]) { #update MIN56$_[4] = $_[0];57}58}5960# subroutine to print the stats for an array61sub PrintStats {62my ($hotness, $samples, $sum, $maxVal, $minVal, $stddev) = @_;63if ($samples > 0) {64# samples max sum avg min65printf "$hotness\t%d\t%.1f\t%.1f\t\t%.0f\t\t%.0f\n", $samples, $maxVal/1000, $sum/1000, $sum/$samples, $minVal;66}67}686970sub processVlog {71# samples, sum, max, min, stddev72my @noopt= (0,0,0,10000000,0);73my @aotload= (0,0,0,10000000,0);74my @aotcold= (0,0,0,10000000,0);75my @aotwarm= (0,0,0,10000000,0);76my @aothot= (0,0,0,10000000,0);77my @cold= (0,0,0,10000000,0);78my @warm= (0,0,0,10000000,0);79my @hot= (0,0,0,10000000,0);80my @phot= (0,0,0,10000000,0);81my @veryhot= (0,0,0,10000000,0);82my @pveryhot= (0,0,0,10000000,0);83my @scorching= (0,0,0,10000000,0);84my @jni= (0,0,0,10000000,0);85my @unknown= (0,0,0,10000000,0);86my @failures= (0,0,0,10000000,0);87my @allt= (0,0,0,10000000,0);88my $numGCR = 0;89my $numGCRNoServer = 0;90my $numPushy = 0;91my $numDLT = 0;92my $numSync = 0;93my $numColdUpgrade = 0;94my $numForcedAOTUpgrade = 0;95my $numAOTUpgrade = 0;96my $numNonAOTUpgrade = 0;97my $numInvalidate = 0;98my $numFailures = 0;99my $max = 0;100my $maxLine = "";101my $maxQSZ = "";102my $numAOTLoadsNotRecompiled = 0;103my $lastTimestamp = 0; # in ms since JVM start104# clear the hash105%methodHash = ();106107my $vlog_filename = shift;108open(VLOG, $vlog_filename) || die "Cannot open $vlog_filename: $!\n";109my @vlog_lines = <VLOG>; # read all lines from VLOG110111# process each line from the file112foreach my $line (@vlog_lines) {113# filter the lines that start with +.114my $compLevel = "";115my $methodName = "";116my $usec = 0;117my $matchFound = 0;118if ($line =~ /\+ \((.+)\) (\S+) \@ .+ time=(\d+)us/) {119$compLevel = $1;120$methodName = $2;121$usec = $3;122$matchFound = 1;123}124# Note that AOT loads have a different format:125elsif ($line =~ /\+ \(AOT load\) (\S+).+\@ /) {126$compLevel = "AOT load";127$methodName = $1;128$matchFound = 1;129}130# If the method name is very long there might be no space between the method name and location in memory131elsif ($line =~ /\+ \((.+)\) (\S+)0x[0-9A-F].+time=(\d+)us/) {132$compLevel = $1;133$methodName = $2;134$usec = $3;135$matchFound = 1;136}137elsif($line =~ /^\! (\S+) time=(\d+)us/) {138$usec = $2;139&UpdateStats($usec, @allt);140&UpdateStats($usec, @failures);141}142143144if ($matchFound) {145146if ($usec > $max) {147$max = $usec;148$maxLine = $line;149}150151# add the method to a hash where the method name is the key152if (exists $methodHash{$methodName}) {153# retrieve the array ref from the hash and then do a push154push(@{$methodHash{$methodName}}, $line);155}156else { # first instance in the hash157# add an anonymous array ref to the hash158$methodHash{$methodName} = [$line];159}160161if ($usec > $compTimeThreshold) {162print $line;163}164165&UpdateStats($usec, @allt);166if ($line =~ / JNI /) {167&UpdateStats($usec, @jni);168}elsif ($compLevel eq "warm") {169&UpdateStats($usec, @warm);170}elsif ($compLevel eq "cold") {171&UpdateStats($usec, @cold);172}elsif ($compLevel eq "AOT load") {173&UpdateStats($usec, @aotload);174}elsif ($compLevel eq "AOT cold") {175&UpdateStats($usec, @aotcold);176}elsif ($compLevel eq "AOT warm") {177&UpdateStats($usec, @aotwarm);178}elsif ($compLevel eq "AOT hot") {179&UpdateStats($usec, @aothot);180}elsif ($compLevel eq "hot") {181&UpdateStats($usec, @hot);182}elsif ($compLevel eq "profiled hot") {183&UpdateStats($usec, @phot);184}elsif ($compLevel eq "very-hot") {185&UpdateStats($usec, @veryhot);186}elsif ($compLevel eq "profiled very-hot") {187&UpdateStats($usec, @pveryhot);188}elsif ($compLevel eq "scorching") {189&UpdateStats($usec, @scorching);190}elsif ($compLevel eq "no-opt") {191&UpdateStats($usec, @noopt);192}else {193&UpdateStats($usec, @unknown);194}195# look at the reason for recompilation196if ($line =~ / G /) {197$numGCR++;198}199elsif ($line =~ / g /) {200$numGCRNoServer++;201}202elsif ($line =~ / P /) {203$numPushy++;204}205elsif ($line =~ / I /) {206$numInvalidate++;207}208elsif ($line =~ / C /) {209$numColdUpgrade++;210}211if ($line =~ / A /) {212$numForcedAOTUpgrade++;213}214if ($line =~ / sync /) {215$numSync++;216}217if ($line =~ / DLT /) {218$numDLT++;219}220if ($line =~ /Q\_SZ=(\d+)/) {221if ($1 > $maxQSZ) {222$maxQSZ = $1;223}224}225}226elsif ($line =~ /^\! /) { # lines starting with !227$numFailures++;228}229elsif ($line =~ /^\+/) { # lines that start with '+' and haven't been tracked by now are errors230print "Unaccounted line: $line";231}232# Track timestamps233if ($line =~ /\st=\s*(\d+)\s/) {234$lastTimestamp = $1;235}236}237print "$vlog_filename\n";238print "\tSamples MAX(ms) TOTAL(ms)\tAVG(usec)\tMIN(usec)\n";239&PrintStats("Total", @allt);240&PrintStats("aotl", @aotload);241&PrintStats("noopt", @noopt);242&PrintStats("cold", @cold);243&PrintStats("aotc", @aotcold);244&PrintStats("aotw", @aotwarm);245&PrintStats("aoth", @aothot);246&PrintStats("warm", @warm);247&PrintStats("hot", @hot);248&PrintStats("phot", @phot);249&PrintStats("vhot", @veryhot);250&PrintStats("pvhot", @pveryhot);251&PrintStats("scorc", @scorching);252&PrintStats("jni", @jni);253&PrintStats("unkn", @unknown);254&PrintStats("fails", @failures);255256257# compute how many upgrades come from AOT and how many from JIT258for my $methodName (keys %methodHash) { # for each method259my $compArrayRef = $methodHash{$methodName}; # get its table of compilations260my $numComp = scalar(@$compArrayRef); # number of compilations for this method261for (my $i = $numComp-1; $i >= 0; $i--) { # for each compilation of said method262if ($compArrayRef->[$i] =~ / C /) { # if the compilation is a cold upgrade263#print $compArrayRef->[$i];264if ($i == 0) { # cold upgrades cannot appear first because thei are recompilations265print "Some error occurred for" . $compArrayRef->[$i];266} else {267if ($compArrayRef->[$i-1] =~ /\+ \(AOT load\)/) {268$numAOTUpgrade++;269} else {270$numNonAOTUpgrade++;271}272#print $compArrayRef->[$i-1] . "\n";273}274next;275}276}277# now look to see how many AOT loads were recompiled278if ($compArrayRef->[0] =~ /AOT load/) { # this is an AOT load279# if there are other compilations, then they are recompilations280if ($numComp == 1) {281$numAOTLoadsNotRecompiled++;282}283}284}285286287print "MAXLINE=$maxLine";288print "numCGR recompilations = $numGCR\n";289print "numgcr recompilations = $numGCRNoServer\n";290print "pushy recompilations = $numPushy\n";291print "coldupgr recompilations = $numColdUpgrade (AOT=$numAOTUpgrade, JIT=$numNonAOTUpgrade\n";292print "forcedAOTupgrades = $numForcedAOTUpgrade\n";293print "numAOTLoadsNotRecompiled= $numAOTLoadsNotRecompiled\n";294print "inv recompilations = $numInvalidate\n";295print "sync compilations = $numSync\n";296print "DLT compilations = $numDLT\n";297print "numFailures = $numFailures\n";298print "max_Q_SZ = $maxQSZ\n";299print "lastTimestamp = $lastTimestamp\n";300301302return $allt[1];303}304305306307