forked from brendangregg/pmc-cloud-tools
-
Notifications
You must be signed in to change notification settings - Fork 0
/
pmcarch
executable file
·115 lines (108 loc) · 3.4 KB
/
pmcarch
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
#!/bin/bash
#
# pmcarch - measure and summarize architectural PMCs. Uses Linux perf.
#
# FROM: https://github.com/brendangregg/pmc-cloud-tools
#
# USAGE: pmcarch {-C CPU | -p PID | -c CMD} [interval [duration]]
#
# PMCs are performance monitoring counters. This script uses the architectural
# set to report on:
#
# - K_CYCLES: CPU Cycles x 1000
# - K_INSTR: CPU Instructions x 1000
# - IPC: Instructions-Per-Cycle
# - BMR%: Branch Misprediction Ratio, as a percentage
# - LLC%: Last Level Cache hit ratio, as a percentage
#
# Copyright 2017 Netflix, Inc.
# Licensed under the Apache License, Version 2.0 (the "License")
#
# 07-Apr-2017 Brendan Gregg Created this.
function usage {
cat <<-END >&2
USAGE: pmcarch {-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,
pmcarch # show stats across all CPUs
pmcarch 5 # show stats every 5 seconds
pmcarch -C 0 # measure CPU 0 only
pmcarch -p 181 # measure PID 181 only
pmcarch -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
# order of PMCs attempts to workaround a 3.13 issue
# cycles are twice as a workaround for an issue
# the raw counters are from the architectural set, so should be stable
perf stat -e cycles -e cycles \
-e r4f2e -e r412e \
-e r00c4 -e r00c5 -e instructions \
-I $(( secs * 1000 )) $target 2>&1 | awk -v hlines=$hlines '
BEGIN {
htxt = sprintf("%-10s %-10s %5s %-12s %-10s %5s %-11s %-10s %5s",
"K_CYCLES", "K_INSTR", "IPC", "BR_RETIRED", "BR_MISPRED", "BMR%",
"LLCREF", "LLCMISS", "LLC%");
print htxt
header = hlines
}
/invalid/ { print $0 } # unsupported event
{ gsub(/,/, ""); }
$3 == "cycles" { cycles = $2; }
$3 == "r4f2e" { llcref = $2; }
$3 == "r412e" { llcmiss = $2; }
$3 == "r00c4" { brretired = $2; }
$3 == "r00c5" {
brmiss = $2
if (brretired > 0) {
brratio = (100 * brmiss) / brretired;
} else {
brratio = 0;
}
}
$3 == "instructions" {
if (--header == 0) {
print htxt
header = hlines
}
ins = $2
if (llcref == 0) { llcref = 1; llcmiss = 0 }
if (cycles == 0) { cycles = 1 } # PMCs are broken, or no events
printf("%-10d %-10d %5.2f %-12d %-10d %5.2f %-11d %-10d %5.2f\n",
cycles / 1000, ins / 1000, ins / cycles, brretired, brmiss,
brratio, llcref, llcmiss, 100 * (llcref - llcmiss) / llcref)
}
'