-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathitlbstat.sh
More file actions
executable file
·151 lines (139 loc) · 5.13 KB
/
Copy pathitlbstat.sh
File metadata and controls
executable file
·151 lines (139 loc) · 5.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#!/usr/bin/env bash
#
# Copyright 2018 Netflix, Inc.
# Licensed under the Apache License, Version 2.0 (the "License")
#
# 08-Jan-2018 Brendan Gregg Created this.
#
# Glossar:
#
# - PMH: Page Miss Handler
#
# Columns:
#
# - K_CYCLES: CPU Cycles x 1000
# - K_INSTR: CPU Instructions x 1000
# - IWALK: Page walk (of any size) caused by a code fetch
# - RET_ITLB: Retired instruction causes ITLB miss
# - K_ITLB_ACT: Number of cycles PMH are busy with a code fetch x 1000
# - ICACHE: Numebr of cycles code fetch is stalled due to L1 instruction cache
# - ICACHEM: Instruction fetch tag lookups that miss in the instruction cache
# - CPUU: Number of core cycles while the thread is not in a halt state
# - IWALK_COMP: Completed page walks (2M and 4M) caused by a code fetch
# - INS_RET_ANY: Number of instructions retired from execution
#
# Additionally, metrics recommended in Intels 'Runtime Performance
# Optimization Blueprint: Intel Architecture Optimization with large code
# pages' can be calculated from the above defined events:
#
# - ITLB_STALLS: Fraction of cycles the CPU was stalled due to ITLB misses
# is calculated via: 100 * (ICACHE / CPUU)
# - ITLB_MPKI: Normalized value which can be used to compare different systems
# is calculated via: 1000 (IWALK_COMP / INS_RET_ANY)
#
source $PWD/common.src
function usage {
cat <<-END >&2
USAGE: tlbstat [-c CMD] [-f FILE] [duration [interval]]
-c 'CMD' # measure this command (quote it)
-f FILE # generated output is saved to FILE
-I INTERVAL # output header every interval in
# secs (default disabled)
interval # output results every interval in secs
# (default 1)
duration # total duration (default 9999)
eg,
tlbstat # show stats across all CPUs
tlbstat 5 # show stats every 5 seconds
tlbstat -c 'cksum /boot/*' # measure run and measure this cmd
END
exit
}
opt_cmd=0; opt_file=0;
cmd=""; file=""
hlines=0; # lines to repeat header
while getopts "c:f:I:h" opt
do
case $opt in
c) opt_cmd=1; cmd=$OPTARG ;;
f) opt_file=1; file=$OPTARG ;;
I) hlines=$OPTARG;;
h|?) usage ;;
esac
done
shift $(( $OPTIND - 1 ))
duration=${1:-9999} # default semi-infinite seconds
secs=${2:-1} # default 1 second
# base target flags
target="--all-cpus -- sleep ${duration}"
# add optargs to target depending on set flag
(( opt_cmd )) && target="$cmd"
(( opt_file )) && [ -z "$file" ] && file="perf-stats"
# note that instructions is last on purpose, it triggers output
# cycles are twice as a workaround for an issue
perf stat -e cycles -e cycles \
-e itlb_misses.miss_causes_a_walk \
-e frontend_retired.itlb_miss \
-e itlb_misses.walk_active \
-e itlb_misses.walk_completed \
-e cpu_clk_unhalted.thread \
-e icache_64b.iftag_stall \
-e icache_64b.iftag_miss \
-e inst_retired.any \
-e instructions \
-I $(( secs * 1000 )) $target 2>&1 | awk \
-v hlines=$hlines -v out="${file}.report" -v interval="$secs" '
BEGIN {
htxt = sprintf("%-10s %-10s %-10s %-10s %-10s %-10s %-10s %-12s %-10s %-10s",
"K_CYCLES", "K_INSTR","IWALK", "RET_ITLB", "K_ITLB_ACT",
"ICACHE", "ICACHEM", "CPUU", "IWALK_COMP", "INS_RET_ANY");
if(out != ""){
file = out
print "Saving output to " out " ..."
print "# Interval time in secs: " interval
printf("%s\n", htxt) > file
}
print htxt
header = hlines
}
/invalid/ { print $0 } # unsupported event
{ gsub(/,/, ""); }
$3 == "cycles" { cycles = $2; }
# counts:
$3 == "itlb_misses.miss_causes_a_walk" { imwalk = $2 }
$3 == "frontend_retired.itlb_miss" { itlb = $2 }
# walk active cycles in at least one PMH cycles:
$3 == "itlb_misses.walk_active" { itlbwc = $2; }
$3 == "itlb_misses.walk_completed" { iwalk = $2; }
$3 == "cpu_clk_unhalted.thread" { cpuu = $2; }
$3 == "icache_64b.iftag_stall" { icac = $2; }
$3 == "icache_64b.iftag_miss" { icacm = $2; }
$3 == "inst_retired.any" { iret = $2; }
$3 == "instructions" {
if (--header == 0) {
print htxt
header = hlines
}
ins = $2
if (cycles == 0) { cycles = 1 } # PMCs are broken, or no events
out = sprintf("%-10d %-10d %-10d %-10d %-10d %-10d %-10d %-12d %-10d %-10d",
cycles / 1000, ins / 1000,
imwalk,
itlb,
itlbwc / 1000,
icac,
icacm,
cpuu,
iwalk,
iret)
if (file != ""){
printf("%s\n", out) >> file
}
print out
# for older versions use system("")
fflush();
}
END {
close(file)
}
'