1 #!/usr/bin/python 2 3 """ 4 python-libpfm4 provides python bindings to the libpfm4 5 library and the perf_event kernel subsystem. This 6 script builds on them to provide a *stat like interface 7 to CPU performance counters. 8 9 Run as: ./cpistat -c cpulist -e eventlist 10 11 Depends on libpfm4: http://perfmon2.sf.net/ 12 13 git://perfmon2.git.sourceforge.net/gitroot/perfmon2/libpfm4 14 """ 15 16 import sys, os, optparse, time, struct, perfmon 17 18 if __name__ == '__main__': 19 parser = optparse.OptionParser() 20 parser.add_option('-e', '--events', help='Events to use', 21 action='store', dest='events') 22 parser.add_option('-c', '--cpulist', help='CPUs to monitor', 23 action='store', dest='cpulist') 24 parser.set_defaults(events='PERF_COUNT_HW_CPU_CYCLES,' + 25 'PERF_COUNT_HW_INSTRUCTIONS') 26 (options, args) = parser.parse_args() 27 28 show_per_cpu = False 29 if not options.cpulist: 30 ncpus = os.sysconf('SC_NPROCESSORS_ONLN') 31 cpus = range(0, ncpus) 32 else: 33 cpus = options.cpulist.split(',') 34 cpus = [ int(c) for c in cpus ] 35 show_per_cpu = True 36 37 if options.events: 38 events = options.events.split(',') 39 else: 40 raise ValueError('You need to specify events to monitor') 41 42 s = perfmon.SystemWideSession(cpus, events) 43 44 s.start() 45 # Measuring loop 46 interval = 1 47 iters = -1 48 infinite = True 49 if len(args) == 2: 50 interval = int(args[0]) 51 iters = int(args[1]) 52 infinite = False 53 54 delta = {} 55 last = {} 56 sum = {} 57 for e in events: 58 delta[e] = {} 59 last[e] = {} 60 sum[e] = {} 61 for c in cpus: 62 delta[e][c] = 0 63 last[e][c] = 0 64 65 while infinite or iters: 66 for i in range(0, len(events)): 67 e = events[i] 68 sum[e] = 0 69 for c in cpus: 70 count = struct.unpack('L', s.read(c, i))[0] 71 delta[e][c] = count - last[e][c] 72 last[e][c] = count 73 if show_per_cpu: 74 print '''CPU%d: %s\t%lu''' % (c, e, delta[e][c]) 75 sum[e] += delta[e][c] 76 77 cycles = sum['PERF_COUNT_HW_CPU_CYCLES'] 78 instructions = sum['PERF_COUNT_HW_INSTRUCTIONS'] 79 CPI = cycles * 1.0/instructions 80 print ('cycles: %12lu, instructions: %12lu, CPI: %2.4f' 81 % (cycles, instructions, CPI)) 82 sys.stdout.flush() 83 time.sleep(interval) 84 iters = iters - 1 85