-
Notifications
You must be signed in to change notification settings - Fork 40
/
icache
executable file
·116 lines (108 loc) · 3.7 KB
/
icache
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
#!/bin/bash
#
# icache - measure instruction cache usage.
# Uses Linux perf and PMCs.
#
# FROM: https://github.com/brendangregg/pmc-cloud-tools
#
# USAGE: icache {-C CPU | -p PID | -c CMD} [interval [duration]]
#
# Columns:
#
# - INS: Instructions x 1000
# - L1IMISS: Level 1 instruction cache misses x 1000
# - L1I%: Level 1 instruction cache hit ratio percent (L1MISS/INS)
# - L2IHIT: Level 2 instruction cache hits x 1000
# - L2IMISS: Level 2 instruction cache misses x 1000
# - L2I%: Level 2 instruction cache hit ratio percent
# - LLCREF: Last Level Cache references x 1000
# - LLCMISS: Last Level Cache misses x 1000
# - LLC%: Last Level Cache hit ratio percent
#
# Copyright 2020 Netflix, Inc.
# Licensed under the Apache License, Version 2.0 (the "License")
#
# 24-Jan-2020 Brendan Gregg Created this.
function usage {
cat <<-END >&2
USAGE: icache {-C CPU | -p PID | -c CMD} [interval [duration]]
-C CPU # measure this CPU only
-p PID # measure this PID only
-c 'CMD' # measure this command only (quote it)
interval # output interval in secs (default 1)
duration # total seconds (default infinityish)
eg,
icache # show stats across all CPUs
icache 5 # show stats every 5 seconds
icache -C 0 # measure CPU 0 only
icache -p 181 # measure PID 181 only
icache -c 'cksum /boot/*' # measure run and measure this cmd
END
exit
}
opt_cpu=0; opt_pid=0; opt_cmd=0; cpu=""; pid=""; cmd=""
while getopts C:p:c:h opt
do
case $opt in
C) opt_cpu=1; cpu=$OPTARG ;;
p) opt_pid=1; pid=$OPTARG ;;
c) opt_cmd=1; cmd=$OPTARG ;;
h|?) usage ;;
esac
done
shift $(( $OPTIND - 1 ))
if (( opt_cpu + opt_pid + opt_cmd > 1 )); then
echo >&2 "ERROR: pick one of -C, -p, -c"
usage
fi
secs=${1:-1} # default 1 second
duration=${2:-999999999} # default semi-infinite seconds
hlines=25 # lines to repeat header
target=-a
(( opt_cpu )) && target="-C $cpu sleep $duration"
(( opt_pid )) && target="-p $pid sleep $duration"
(( opt_cmd )) && target="$cmd"
if (( opt_pid )); then
if [ ! -d /proc/$pid ]; then
echo >&2 "ERROR: Can't find PID $pid. Exiting."
exit
fi
fi
# note that instructions is last on purpose, it triggers output
# cycles are twice as a workaround for an issue
# the r4f2e and r412e counters are from the architectural set, so should be stable
echo "All counter columns are x 1000"
perf stat -e instructions,L1-icache-load-misses,r2424,r4424,cache-references,cache-misses \
-I $(( secs * 1000 )) $target 2>&1 | awk -v hlines=$hlines '
BEGIN {
htxt = sprintf("%-10s %10s %5s %9s %9s %5s %8s %8s %5s",
"INS", "L1IMISS", "L1I%", "L2IHIT", "L2IMISS", "L2I%",
"LLCREF", "LLCMISS", "LLC%");
print htxt
header = hlines
}
/invalid/ { print $0 } # unsupported event
{ gsub(/,/, ""); }
$3 == "instructions" { ins = $2 }
$3 == "L1-icache-load-misses" { l1im = $2 }
$3 == "r2424" { l2im = $2 } # L2_RQSTS.CODE_RD_MISS
$3 == "r4424" { l2ih = $2 } # L2_RQSTS.CODE_RD_HIT
$3 == "cache-references" { llcr = $2 }
$3 == "cache-misses" { # last one, trigger output
llcm = $2
if (--header == 0) {
print htxt
header = hlines
}
# if we are missing refs, then also reset hits to zero, to avoid a bogus ratio:
if (ins == 0) { ins = 1; l1im = 0 }
if (l2im == 0) { l2im = 1; l2ih = 0 }
if (llcr == 0) { llcr = 1; llcm = 0 }
l1iratio = 100 * (ins - l1im) / ins
l2iratio = 100 * l2ih / (l2ih + l2im)
llcratio = 100 * (llcr - llcm) / llcr
printf("%-10d %10d %5.2f %9d %9d %5.2f %8d %8d %5.2f\n",
ins / 1000, l1im / 1000, l1iratio, l2ih / 1000, l2im / 1000, l2iratio,
llcr / 1000, llcm / 1000, llcratio);
}
'