diff options
-rwxr-xr-x | tools/intel_gpu_analyze.py | 117 |
1 files changed, 109 insertions, 8 deletions
diff --git a/tools/intel_gpu_analyze.py b/tools/intel_gpu_analyze.py index 252e327..a9edcfe 100755 --- a/tools/intel_gpu_analyze.py +++ b/tools/intel_gpu_analyze.py @@ -8,9 +8,6 @@ import os import getopt import tempfile -# for charts -import pylab - HEADER=""" <html> <head> @@ -52,6 +49,30 @@ FIGURE=""" </p> """ +PERF_ITERATION=""" +<hr/> +<a name="%(sec)d"> +<h3>Second %(sec)d</h3> +</a> +Processes in execution: <i>%(processes)s</i> +<br/> +""" + +PERF_SECOND_TITLE=""" +<a href="#%(sec)d">Second %(sec)d</a> +<br/> +""" + +PERF_PROCESS=""" +<h3>Process %(process)s</h3> +""" + +PERF_TOP=""" +<pre> +%(top)s +</pre> +""" + TAIL=""" </body> </html> @@ -99,6 +120,70 @@ def collect(fd): results['blitter_ops'].append(int(data[11])) return results +def analyse_perf(logfile, out_dir, perf="perf.html"): + """Analyses perf results""" + perf_data = os.popen("perf script -f comm,pid,time,ip,sym -i %s 2>/dev/null" % logfile) + if not perf_data: + print "Error: unable to process perf log %s" % logfile + return + results = {} + time_start = -1 + time_prev = -1 + while 1: + line = perf_data.readline() + if not line: + break + fields = line.strip().split() + process = fields[0] + pid = int(fields[1]) + time = float(fields[2][:-1]) # remove the trailing ':' + ip = fields[3] + if len(fields) > 4: + function = fields[4] + else: + function = "unknown" + # calculate time + if time_start == -1: + time_start = int(time) # floor down to the corresponding second + # are we on the next second already? + if time - time_start > 1.0: + time_start = int(time) + if time_start not in results: + results[time_start] = {} + # is the current process being tracked? + if process not in results[time_start]: + results[time_start][process]={} + # calculate times for functions + if function not in results[time_start][process]: + results[time_start][process][function] = 0 + + # ok, so now calculate per-function per-process stats + results[time_start][process][function] += (time - time_prev) + time_prev = time + + # all done, now process the results + output = open("%s/%s" % (out_dir, perf), "w") + print >>output, HEADER % {'title': 'Perf results for %s' % logfile, + 'duration': len(results.keys()) + } + seconds = results.keys() + seconds.sort() + for sec in seconds: + # print TOC + print >>output, PERF_SECOND_TITLE % {'sec': sec} + for sec in seconds: + print >>output, PERF_ITERATION % {'sec': sec, 'processes': ', '.join(results[sec].keys())} + for process in results[sec]: + print >>output, PERF_PROCESS % {'process': process} + # let's sort functions + functions_by_time = sorted(results[sec][process], key=lambda key: results[sec][process][key], reverse=True) + top = "" + for function in functions_by_time: + top += "%.6f\t\t%s\n" % (results[sec][process][function], function) + print >>output, PERF_TOP % { 'top': top } + print >>output, TAIL + output.close() + def analyse(results, title, out_dir, summary="index.html"): """Analyses intel_gpu_top results""" # calculate min/max/avg values @@ -147,6 +232,11 @@ def analyse(results, title, out_dir, summary="index.html"): } # graphics + try: + import pylab + except: + print "Error: unable to import pylab: %s" % sys.exc_value + return fig = pylab.figure() ax = pylab.subplot(111) pylab.title("Summary of CPU/GPU/Power usage") @@ -304,6 +394,7 @@ def analyse(results, title, out_dir, summary="index.html"): pass print >>output, TAIL + output.close() def usage(cmd): """Prints usage message""" @@ -317,8 +408,11 @@ The following arguments are accepted: -c, --command command to profile -t, --title description of the command analysed -o, --output output directory for the results + -p, --perf kernel perf log file to analyse. + +You need to specify either a log file to analyse, or a command to profile, +or a perf log file to process. -You need to specify either a log file to analyse, or a command to profile. When you specify both -l and -c, the last one takes predence. If you do not give a log file to analyse, or a command to profile, this @@ -329,11 +423,12 @@ you will feel bad about it. if __name__ == "__main__": # parse command line try: - opt, args = getopt.getopt(sys.argv[1:], 'hl:c:t:o:', ['help', 'logfile=', 'command=', 'title=', 'output=']) + opt, args = getopt.getopt(sys.argv[1:], 'hl:c:t:o:p:', ['help', 'logfile=', 'command=', 'title=', 'output=', 'perf=']) except getopt.error: usage(sys.argv[0]) sys.exit(1) logfile = None + perf_logfile = None title = None output = os.curdir for o in opt: @@ -342,6 +437,9 @@ if __name__ == "__main__": usage(sys.argv[0]) sys.exit(0) # list + elif o[0] == '-p' or o[0] == '--perf': + perf_logfile = o[1] + print "Analysing perf log file: %s" % perf_logfile elif o[0] == '-l' or o[0] == '--logfile': logfile = open(o[1], "r") title = "Log file '%s'" % o[1] @@ -353,7 +451,7 @@ if __name__ == "__main__": title = o[1] elif o[0] == '-o' or o[0] == '--output': output = o[1] - if not logfile: + if not logfile and not perf_logfile: usage(sys.argv[0]) print "Error: no log file and no command to profile, don't know what to do" sys.exit(1) @@ -361,5 +459,8 @@ if __name__ == "__main__": os.makedirs(output) except: pass - results = collect(logfile) - analyse(results, title, output) + if logfile: + results = collect(logfile) + analyse(results, title, output) + if perf_logfile: + analyse_perf(perf_logfile, output) |