#!/usr/bin/perl use strict; use daveperl; my $h ={}; my $counts = {}; my $cumulative_time = {}; my $total = 0; my $min_tsc_delta = 9999999999999999; while (my $line = <>) { chomp $line; # thunderbird-9460 [000] ...2 226.709428: tlb_flush: pages: 1 reason: 4 (TLB_LOCAL_MM_SHOOTDOWN) # thunderbird-9460 [000] ...2 226.709428: tlb_flush: pages: 1 reason: 5 (TLB_LOCAL_MM_SHOOTDOWN_DONE) my $cpu = $line; $cpu =~ s/.*\[(\d\d\d)\].*/\1/; $cpu = int($cpu); next if ! $cpu; my $reason = $line; $reason =~ s/.*reason: (\d+) .*/\1/; my $pages = $line; $pages =~ s/.*pages: ([-\d]+) .*/\1/; $pages = int($pages); print "$line\n" if ! $pages; my $tsc = $line; $tsc =~ s/.*\s(\d+):\s+tlb_flush:.*/\1/; dprint2 $tsc." ".$reason." ".$cpu."\n"; if ($reason == 4) { $h->{$cpu} = {}; $h->{$cpu}->{tsc} = $tsc; $h->{$cpu}->{reason} = $reason; $h->{$cpu}->{pages} = $pages; $counts->{$pages} = 0 if ! defined $counts->{$pages}; $counts->{$pages}++; $total++; } elsif ($reason == 5) { if (! defined $h->{$cpu}) { warn "crap no $cpu"; next; } my $tsc_prev = $h->{$cpu}->{tsc}; my $tsc_delta = ($tsc - $h->{$cpu}->{tsc}); my $prev_pages = $h->{$cpu}->{pages}; my $tmp = $h->{$cpu}; delete $h->{$cpu}; next if $tsc_delta < 0; $min_tsc_delta = $tsc_delta if $tsc_delta < $min_tsc_delta; if (! defined $cumulative_time->{$prev_pages}) { my @a = (); $cumulative_time->{$prev_pages} = \@a; } push @{$cumulative_time->{$prev_pages}}, $tsc_delta; if ($tsc_delta > 50000) { printf "%6d cycles pages: %4d after: %4d\n", $tsc_delta, $prev_pages, $pages; } } dprintf5 $line."\n"; } sub avg { my $tot = 0; my $size = 0; while (scalar(@_)) { $tot += shift(@_); $size++; } return -1 if ! $size; return $tot / $size; } my $cumulative = 0; foreach my $pages (sort { $a <=> $b } keys %$counts) { my $per = 100.0 * $counts->{$pages} / $total; $cumulative += $per; my $time_samples; my $avg_time = avg(@{$cumulative_time->{$pages}}); if (! defined $cumulative_time->{$pages}) { $avg_time = -2; $time_samples = -3; } else { $time_samples = scalar(@{$cumulative_time->{$pages}}); } next if $time_samples < 50; printf "%6d: %6.2f%% %6.2f%% avg cycles: %5d cycles/page: %4d samples: %d\n", $pages, $per, $cumulative, $avg_time, int($avg_time/$pages), $time_samples; } printf "min_tsc_delta: $min_tsc_delta\n";