1
0
Files
2022-09-29 17:59:04 +03:00

137 lines
4.1 KiB
Perl
Executable File

#!/usr/bin/perl
#
# prfcmp:
#
# Process two ``prfpr'' output streams and display the results side by
# side with computed deltas. The results are sorted by deltas, largest
# to smallest.
#
# The optional cutoff% arg specifies the cutoff point below which a function
# is not printed. The cutoff must hold true for both output streams.
#
if ($#ARGV != 1 && $#ARGV != 2) {
printf STDERR "usage: $0 prfpr1.out prfpr2.out [cutoff%]\n";
exit 1;
}
if ($#ARGV == 2) {
$cutoff = @ARGV[2];
} else {
$cutoff=0.5; # default
}
#
# Convert prfpr streams to arrays.
#
%sarray1 = &convert_prfpr_to_sample_array(@ARGV[0]);
%sarray2 = &convert_prfpr_to_sample_array(@ARGV[1]);
#
# Compute delta array.
#
%delta = %sarray2;
foreach $f (keys(%sarray1)) {
$delta{$f} -= $sarray1{$f};
}
#
# Print summary.
#
print "\n";
print "Profiling Summary Run1 Run2 R2/R1\n";
print "Sum of all cpus (sec) (sec)\n";
print "-------------------------------------------------------\n";
printf "%-21s%8s %8s\n", "Number of cpu's",
$sarray1{"NUMBER-CPUS"}, $sarray2{"NUMBER-CPUS"};
printf "%-24s%8.3f %8.3f %8.2f\n", "Elapsed time",
$sarray1{"TOTAL-SAMPLES"}*.001, $sarray2{"TOTAL-SAMPLES"}*.001,
defined($sarray1{"TOTAL-SAMPLES"}) ?
sprintf("%-8.2f", $sarray2{"TOTAL-SAMPLES"}/$sarray1{"TOTAL-SAMPLES"}) :"";
printf "%-24s%8.3f %8.3f %8.2f\n", "Idle time",
$sarray1{"IDLE-SAMPLES"}*.001, $sarray2{"IDLE-SAMPLES"}*.001,
defined($sarray1{"IDLE-SAMPLES"}) ?
sprintf("%-8.2f", $sarray2{"IDLE-SAMPLES"}/$sarray1{"IDLE-SAMPLES"}) : "";
printf "%-24s%8.3f %8.3f %8.2f\n", "CPU time",
$sarray1{"CPU-SAMPLES"}*.001, $sarray2{"CPU-SAMPLES"}*.001,
defined($sarray1{"CPU-SAMPLES"}) ?
sprintf("%-8.2f", $sarray2{"CPU-SAMPLES"}/$sarray1{"CPU-SAMPLES"}) : "";
#
# CPU time analysis
#
print "\n\n";
print "CPU Time Analysis Run1 Run2 R2-R1 R2-R1/total R1 CPU\n";
printf "Function (cutoff=%3.2f%%) (sec) (sec) (sec) (%%)\n", $cutoff;
print "-----------------------------------------------------------------------------\n";
foreach $f (sort(bydelta keys(%delta))) {
next if $f eq "TOTAL-SAMPLES";
next if $f eq "IDLE-SAMPLES";
next if $f eq "CPU-SAMPLES";
next if $f eq "NUMBER-CPUS";
next if $f eq "idle";
next if $f eq "checkRunq";
$fp1 = $sarray1{$f}/$sarray1{"CPU-SAMPLES"}*100.0;
$fp2 = $sarray2{$f}/$sarray2{"CPU-SAMPLES"}*100.0;
if (!defined($sarray1{$f}) || $fp1 < $cutoff) {
if (!defined($sarray2{$f}) || $fp2 < $cutoff) {
next;
}
}
printf "%-24s%8s %8s %8.3f %8.2f\n", $f,
defined($sarray1{$f}) ? sprintf("%8.3f", $sarray1{$f}*.001) : "",
defined($sarray2{$f}) ? sprintf("%8.3f", $sarray2{$f}*.001) : "",
$delta{$f}*.001, $delta{$f}/$sarray1{"CPU-SAMPLES"}*100.0;
}
print "\n";
print "Notes: 1 msec profiling sample rate.\n";
print " idle time calcualted as sum of \"idle\" and \"checkRunq\" functions.\n";
#
# Comparison function.
#
sub bydelta {
$delta{$b} <=> $delta{$a};
}
#
# Return an associative array containing (function name, num samples)
# (key, value) tuples. Some special tuples are also returned, keyed
# by the following special keys:
# TOTAL-SAMPLES
# CPU-SAMPLES
# IDLE-SAMPLES
# NUMBER-CPUS
#
sub convert_prfpr_to_sample_array {
local($filename) = @_;
local(@line, $cpu_samples, $cur_samples, %sample_array);
if (!open(FILE, $filename)) {
print STDERR "$0: unable to open \"$filename\"\n";
exit 1;
}
cpu: while (<FILE>) {
@line = split(/[\s\t\n]+/, $_);
next if (@line[0] ne "CPU");
$cpu_samples = @line[3];
$sample_array{"TOTAL-SAMPLES"} += $cpu_samples;
$sample_array{"NUMBER-CPUS"}++;
while (<FILE>) {
@line = split(/[\s\t\n]+/, $_);
last if (@line[0] eq "");
last cpu if (@line[0] eq "Total");
$cur_samples = $line[1]*$cpu_samples/100.0;
$sample_array{$line[0]} += $cur_samples;
if (@line[0] eq "idle" || @line[0] eq "checkRunq") {
$sample_array{"IDLE-SAMPLES"} += $cur_samples;
} else {
$sample_array{"CPU-SAMPLES"} += $cur_samples;
}
}
}
close(FILE);
%sample_array;
}