#!/usr/bin/python2 """ python-libpfm4 provides python bindings to the libpfm4 library and the perf_event kernel subsystem. This script builds on them to provide a *stat like interface to CPU performance counters. Run as: ./cpistat -c cpulist -e eventlist Depends on libpfm4: http://perfmon2.sf.net/ git://perfmon2.git.sourceforge.net/gitroot/perfmon2/libpfm4 """ from __future__ import absolute_import from __future__ import division from __future__ import print_function import sys, os, optparse, time, struct, perfmon from six.moves import range if __name__ == '__main__': parser = optparse.OptionParser() parser.add_option('-e', '--events', help='Events to use', action='store', dest='events') parser.add_option('-c', '--cpulist', help='CPUs to monitor', action='store', dest='cpulist') parser.set_defaults(events='PERF_COUNT_HW_CPU_CYCLES,' + 'PERF_COUNT_HW_INSTRUCTIONS') (options, args) = parser.parse_args() show_per_cpu = False if not options.cpulist: ncpus = os.sysconf('SC_NPROCESSORS_ONLN') cpus = list(range(0, ncpus)) else: cpus = options.cpulist.split(',') cpus = [ int(c) for c in cpus ] show_per_cpu = True if options.events: events = options.events.split(',') else: raise ValueError('You need to specify events to monitor') s = perfmon.SystemWideSession(cpus, events) s.start() # Measuring loop interval = 1 iters = -1 infinite = True if len(args) == 2: interval = int(args[0]) iters = int(args[1]) infinite = False delta = {} last = {} sum = {} for e in events: delta[e] = {} last[e] = {} sum[e] = {} for c in cpus: delta[e][c] = 0 last[e][c] = 0 while infinite or iters: for i in range(0, len(events)): e = events[i] sum[e] = 0 for c in cpus: count = struct.unpack('L', s.read(c, i))[0] delta[e][c] = count - last[e][c] last[e][c] = count if show_per_cpu: print('''CPU%d: %s\t%lu''' % (c, e, delta[e][c])) sum[e] += delta[e][c] cycles = sum['PERF_COUNT_HW_CPU_CYCLES'] instructions = sum['PERF_COUNT_HW_INSTRUCTIONS'] CPI = cycles * 1.0/instructions print('cycles: %12lu, instructions: %12lu, CPI: %2.4f' % (cycles, instructions, CPI)) sys.stdout.flush() time.sleep(interval) iters = iters - 1