| rev |
line source |
|
msach@4
|
1 #! /usr/bin/env python
|
|
msach@4
|
2 # -*- coding: utf-8 -*-
|
|
msach@4
|
3
|
|
msach@4
|
4 import sys
|
|
msach@4
|
5 from re import match, search
|
|
msach@4
|
6 from pprint import pformat
|
|
msach@4
|
7 from datetime import datetime
|
|
msach@4
|
8 from subprocess import call,Popen,PIPE
|
|
msach@4
|
9
|
|
msach@4
|
10 """
|
|
msach@4
|
11 This script generates a graph that represents the overhead
|
|
msach@4
|
12
|
|
msach@4
|
13 involved in synchronisation operations
|
|
msach@4
|
14 This script generates results for 5 runs per threads and iteration in
|
|
msach@4
|
15 TOTAL_THREADS_TABLE and ITER_PER_TASK_TABLE
|
|
msach@4
|
16 """
|
|
msach@4
|
17
|
|
msach@4
|
18 usage="""
|
|
msach@4
|
19 This runs the exec time vs task size in three levels of loop nest. The outer most iterates through
|
|
msach@4
|
20 a selection of numbers-of-thread. For each of those, the next lever iterates over a number of work-loops-per-task
|
|
msach@4
|
21 values. The innermost repeats several times and chooses the best.
|
|
msach@4
|
22 Finally, it generates an output file for each value of number-of-threads that give the number of all runs.
|
|
msach@4
|
23 It is expected that the output directory's path is meaningful, such as machine-name, date, and so on
|
|
msach@4
|
24 Usage:
|
|
msach@4
|
25 %s [executable binary] [path to output dir]
|
|
msach@4
|
26 """ % sys.argv[0]
|
|
msach@4
|
27
|
|
msach@4
|
28 NUM_CORES = 4 #Number of Cores the code was compiled for
|
|
msach@4
|
29 ITERS_PER_TASK_TABLE = [2, 5, 10, 20, 40, 80, 160, 320, 640] #Number of iterations of inner loop
|
|
msach@4
|
30 TASKS_PER_THREAD = 30000 #Number of interations of outer loop
|
|
msach@4
|
31 TOTAL_THREADS_TABLE = [8, 32, 128, 512]
|
|
msach@4
|
32
|
|
msach@4
|
33 def getNumber(line):
|
|
msach@4
|
34 match_obj = search("(\d+\.?\d*)", line)
|
|
msach@4
|
35 if match_obj != None:
|
|
msach@4
|
36 return match_obj.groups()[0]
|
|
msach@4
|
37 else:
|
|
msach@4
|
38 raise ValueError
|
|
msach@4
|
39
|
|
msach@4
|
40 if len(sys.argv) != 3:
|
|
msach@4
|
41 print usage
|
|
msach@4
|
42 sys.exit(0)
|
|
msach@4
|
43
|
|
msach@4
|
44 cmd=sys.argv[1]
|
|
msach@4
|
45 try:
|
|
msach@4
|
46 f = open(cmd)
|
|
msach@4
|
47 except IOError:
|
|
msach@4
|
48 print "Please provide a valid executable."
|
|
msach@4
|
49 f.close()
|
|
msach@4
|
50 sys.exit(1)
|
|
msach@4
|
51 finally:
|
|
msach@4
|
52 f.close()
|
|
msach@4
|
53
|
|
msach@4
|
54 output_dir_path = sys.argv[2]
|
|
msach@4
|
55
|
|
msach@4
|
56 #===================================================================
|
|
msach@4
|
57 # Done with parsing cmd line inputs, start doing the runs
|
|
msach@4
|
58 #
|
|
msach@4
|
59
|
|
msach@4
|
60 for totalThreads in TOTAL_THREADS_TABLE:
|
|
msach@4
|
61 print "\nDoing run with %d threads" % totalThreads
|
|
msach@4
|
62 output = "%s/%d_thds__o%d__perfCtrs.meas" % (output_dir_path, totalThreads, TASKS_PER_THREAD)
|
|
msach@4
|
63 print "output file: %s" % output
|
|
msach@4
|
64 threadsPerCore = totalThreads/NUM_CORES
|
|
msach@4
|
65 array_of_results = {}
|
|
msach@4
|
66 for workload_iterations_in_task in ITERS_PER_TASK_TABLE:
|
|
msach@4
|
67 print "Run for %s workload iterations in a task" % workload_iterations_in_task
|
|
msach@4
|
68 results = []
|
|
msach@4
|
69 for run in range(5):
|
|
msach@4
|
70 print "Run %d" % run,
|
|
msach@4
|
71 program_output = Popen("%s -t %d -i %d -o %d" % (cmd,
|
|
msach@4
|
72 totalThreads,
|
|
msach@4
|
73 workload_iterations_in_task,
|
|
msach@4
|
74 TASKS_PER_THREAD),
|
|
msach@4
|
75 stdout=PIPE, stderr=None, shell=True).stdout.read()
|
|
msach@4
|
76 #parse arguments for
|
|
msach@4
|
77 for line in program_output.split("\n"):
|
|
msach@4
|
78 if match("^Sum across threads of work cycles:", line) != None:
|
|
msach@4
|
79 total_workcycles = int(getNumber(line))
|
|
msach@4
|
80 if match("^Total Execution Cycles:", line) != None:
|
|
msach@4
|
81 total_exe_cycles = int(getNumber(line))
|
|
msach@4
|
82 if match("^ExeCycles/WorkCycles Ratio", line) != None:
|
|
msach@4
|
83 exeCycles_workCycles_ratio = float(getNumber(line))
|
|
msach@4
|
84 results.append({"total_workcycles" : total_workcycles,
|
|
msach@4
|
85 "total_exe_cycles" : total_exe_cycles,
|
|
msach@4
|
86 "exeCycles_workCycles_ratio" : exeCycles_workCycles_ratio})
|
|
msach@4
|
87 print "ratio %f" % exeCycles_workCycles_ratio
|
|
msach@4
|
88 array_of_results[workload_iterations_in_task] = results
|
|
msach@4
|
89
|
|
msach@4
|
90 #open file to output data
|
|
msach@4
|
91 try:
|
|
msach@4
|
92 data_output = open(output,"w")
|
|
msach@4
|
93 except IOError:
|
|
msach@4
|
94 print "Cannot open output file %s" % output
|
|
msach@4
|
95 sys.exit(1)
|
|
msach@4
|
96
|
|
msach@4
|
97 #output relevant data to file
|
|
msach@4
|
98 data_output.write(";\n".join(["# This is a output of the overhead_data_generation.py script, run the overhead_result_calc.py script to get the calculated results",
|
|
msach@4
|
99 "data_filename = " + pformat(output),
|
|
msach@4
|
100 "NUM_CORES = " + pformat(NUM_CORES),
|
|
msach@4
|
101 "ITERS_PER_TASK_TABLE = " + pformat(ITERS_PER_TASK_TABLE),
|
|
msach@4
|
102 "TASKS_PER_THREAD = " + pformat(TASKS_PER_THREAD),
|
|
msach@4
|
103 "date_of_run = " + pformat(datetime.now()),
|
|
msach@4
|
104 "threads_per_core = " + pformat(threadsPerCore),
|
|
msach@4
|
105 "totalThreads = " + pformat(totalThreads),
|
|
msach@4
|
106 "# array_of_results: hash key is the number of iterations per task(inner iterations)",
|
|
msach@4
|
107 "array_of_results = " + pformat(array_of_results)]))
|
|
msach@4
|
108
|
|
msach@4
|
109
|
|
msach@4
|
110 data_output.close()
|
|
msach@4
|
111
|