perf test: Add shadow stat test

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>
This commit is contained in:
Namhyung Kim 2020-11-27 13:14:04 +09:00 committed by Arnaldo Carvalho de Melo
parent 1f195e557d
commit 94b69c615e

View File

@ -0,0 +1,80 @@
#!/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