-
Notifications
You must be signed in to change notification settings - Fork 40
/
resstalls
executable file
·113 lines (105 loc) · 3.67 KB
/
resstalls
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
#!/bin/bash
#
# resstalls - measure and summarize resource stalls.
# Uses Linux perf and PMCs.
#
# FROM: https://github.com/brendangregg/pmc-cloud-tools
#
# USAGE: resstalls {-C CPU | -p PID | -c CMD} [interval [duration]]
#
# Columns:
#
# - ALL: Resource stalls x 1M
# - LOAD: Load buffer stalls x 1M
# - PIPE: Instruction pipeline reservation station full stalls x 1M
# - STORE: Store related stall x 1M
# - ROB: Re-order buffer full store x 1M
# - FLOAT: Floating point unit control word stall x 1M
# - MXCSR: MXCSR register rename stall x 1M
# - OTHER: Other stall reasons x 1M
# - SUM: Sum of all columns except ALL
#
# 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: resstalls {-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,
resstalls # show stats across all CPUs
resstalls 5 # show stats every 5 seconds
resstalls -C 0 # measure CPU 0 only
resstalls -p 181 # measure PID 181 only
resstalls -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 1000000"
perf stat -e resource_stalls.any,r02a2,r04a2,r08a2,r10a2,r20a2,r40a2,r80a2 \
-I $(( secs * 1000 )) $target 2>&1 | awk -v hlines=$hlines '
BEGIN {
htxt = sprintf("%8s %8s %8s %8s %8s %8s %8s %8s %8s",
"ALL", "LOAD", "PIPE", "STORE", "ROB", "FLOAT",
"MXCSR", "OTHER", "SUM");
print htxt
header = hlines
}
/invalid/ { print $0 } # unsupported event
{ gsub(/,/, ""); }
$3 == "resource_stalls.any" { rsany = $2 } # RESOURCE_STALLS.ANY
$3 == "r02a2" { rsload = $2 } # RESOURCE_STALLS.LOAD
$3 == "r04a2" { rspipe = $2 } # RESOURCE_STALLS.RS_FULL
$3 == "r08a2" { rsstore = $2 } # RESOURCE_STALLS.STORE
$3 == "r10a2" { rsrob = $2 } # RESOURCE_STALLS.ROB_FULL
$3 == "r20a2" { rsfpcw = $2 } # RESOURCE_STALLS.FPCW
$3 == "r40a2" { rsmxcsr = $2 } # RESOURCE_STALLS.MXCSR
$3 == "r80a2" { # last one, trigger output
rsother = $2 # RESOURCE_STALLS.OTHER
if (--header == 0) {
print htxt
header = hlines
}
rssum = rsload + rspipe + rsstore + rsrob + rsfpcw + rsmxcsr + rsother
printf("%8.1f %8.1f %8.1f %8.1f %8.1f %8.1f %8.1f %8.1f %8.1f\n",
rsany / 1000000, rsload / 1000000, rspipe / 1000000,
rsstore / 1000000, rsrob / 1000000, rsfpcw / 1000000,
rsmxcsr / 1000000, rsother / 1000000, rssum / 1000000)
}
'