It calculates IPC from the cycles and instruction counts and compares it with the shadow stat for both global aggregation (default) and no aggregation mode. $ perf stat -a -A -e cycles,instructions sleep 1 Performance counter stats for 'system wide': CPU0 39,580,880 cycles CPU1 45,426,945 cycles CPU2 31,151,685 cycles CPU3 55,167,421 cycles CPU0 17,073,564 instructions # 0.43 insn per cycle CPU1 34,955,764 instructions # 0.77 insn per cycle CPU2 15,688,459 instructions # 0.50 insn per cycle CPU3 34,699,217 instructions # 0.63 insn per cycle 1.003275495 seconds time elapsed In this example, the 'insn per cycle' should be matched to the number for each cpu. For CPU2, 0.50 = 15,688,459 / 31,151,685 . Committer testing: # perf test shadow 78: perf stat metrics (shadow stat) test : Ok # Signed-off-by: Namhyung Kim <namhyung@kernel.org> Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com> Acked-by: Jiri Olsa <jolsa@redhat.com> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Ian Rogers <irogers@google.com> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Link: http://lore.kernel.org/lkml/20201127041404.390276-2-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
80 lines
1.5 KiB
Bash
Executable file
80 lines
1.5 KiB
Bash
Executable file
#!/bin/sh
|
|
# perf stat metrics (shadow stat) test
|
|
# SPDX-License-Identifier: GPL-2.0
|
|
|
|
set -e
|
|
|
|
# skip if system-wide mode is forbidden
|
|
perf stat -a true > /dev/null 2>&1 || exit 2
|
|
|
|
test_global_aggr()
|
|
{
|
|
local cyc
|
|
|
|
perf stat -a --no-big-num -e cycles,instructions sleep 1 2>&1 | \
|
|
grep -e cycles -e instructions | \
|
|
while read num evt hash ipc rest
|
|
do
|
|
# skip not counted events
|
|
if [[ $num == "<not" ]]; then
|
|
continue
|
|
fi
|
|
|
|
# save cycles count
|
|
if [[ $evt == "cycles" ]]; then
|
|
cyc=$num
|
|
continue
|
|
fi
|
|
|
|
# skip if no cycles
|
|
if [[ -z $cyc ]]; then
|
|
continue
|
|
fi
|
|
|
|
# use printf for rounding and a leading zero
|
|
local res=`printf "%.2f" $(echo "scale=6; $num / $cyc" | bc -q)`
|
|
if [[ $ipc != $res ]]; then
|
|
echo "IPC is different: $res != $ipc ($num / $cyc)"
|
|
exit 1
|
|
fi
|
|
done
|
|
}
|
|
|
|
test_no_aggr()
|
|
{
|
|
declare -A results
|
|
|
|
perf stat -a -A --no-big-num -e cycles,instructions sleep 1 2>&1 | \
|
|
grep ^CPU | \
|
|
while read cpu num evt hash ipc rest
|
|
do
|
|
# skip not counted events
|
|
if [[ $num == "<not" ]]; then
|
|
continue
|
|
fi
|
|
|
|
# save cycles count
|
|
if [[ $evt == "cycles" ]]; then
|
|
results[$cpu]=$num
|
|
continue
|
|
fi
|
|
|
|
# skip if no cycles
|
|
local cyc=${results[$cpu]}
|
|
if [[ -z $cyc ]]; then
|
|
continue
|
|
fi
|
|
|
|
# use printf for rounding and a leading zero
|
|
local res=`printf "%.2f" $(echo "scale=6; $num / $cyc" | bc -q)`
|
|
if [[ $ipc != $res ]]; then
|
|
echo "IPC is different for $cpu: $res != $ipc ($num / $cyc)"
|
|
exit 1
|
|
fi
|
|
done
|
|
}
|
|
|
|
test_global_aggr
|
|
test_no_aggr
|
|
|
|
exit 0
|