summaryrefslogtreecommitdiffstats
path: root/smt_analysis
diff options
context:
space:
mode:
Diffstat (limited to 'smt_analysis')
-rwxr-xr-xsmt_analysis/computeLCslowdown.py73
-rwxr-xr-xsmt_analysis/computeSMTslowdown.py154
-rwxr-xr-xsmt_analysis/libSMT.py151
3 files changed, 233 insertions, 145 deletions
diff --git a/smt_analysis/computeLCslowdown.py b/smt_analysis/computeLCslowdown.py
new file mode 100755
index 0000000..bcd22da
--- /dev/null
+++ b/smt_analysis/computeLCslowdown.py
@@ -0,0 +1,73 @@
1#!/usr/bin/python3
2import numpy as np
3import sys
4import plotille.plotille as plt
5from libSMT import *
6TIMING_ERROR = 1000 #ns
7ASYNC_FORMAT = False
8
9def print_usage():
10 print("This program takes in the all-pairs and baseline SMT data and computes the worst-case slowdown against any other task when SMT is enabled.", file=sys.stderr)
11 print("Level-A/B usage: {} <file -A> <file -B> <baseline file>".format(sys.argv[0]), file=sys.stderr)
12 print("Level-C usage: {} <continuous pairs> <baseline file>".format(sys.argv[0]), file=sys.stderr)
13
14# Check that we got the right number of parameters
15if len(sys.argv) < 3:
16 print_usage()
17 exit()
18
19if len(sys.argv) > 3:
20 print("Reading file using synchronous pair format...")
21 print("Are you sure you want to do this? For the RTAS'21 paper, L-A/-B pairs should use the other script.")
22 input("Press enter to continue, Ctrl+C to exit...")
23else:
24 print("Reading file using asynchronous pair format...")
25 ASYNC_FORMAT = True
26
27assert_valid_input_files(sys.argv[1:-1], print_usage)
28
29# Pull in the data
30if not ASYNC_FORMAT:
31 baseline_times, baseline_sample_cnt, baseline_max_times = load_baseline(sys.argv[3])
32 paired_times, paired_offsets, name_to_idx, idx_to_name = load_paired(sys.argv[1], sys.argv[2], len(list(baseline_times.keys())))
33 for key in baseline_times:
34 print(key,max(baseline_times[key]))
35else:
36 baseline_times, baseline_sample_cnt, baseline_max_times = load_baseline(sys.argv[2])
37 paired_times, name_to_idx, idx_to_name = load_fake_paired(sys.argv[1])
38
39# We work iff the baseline was run for the same set of benchmarks as the pairs were
40assert_base_and_pair_keys_match(baseline_times, name_to_idx)
41
42# Only consider benchmarks that are at least an order of magnitude longer than the timing error
43reliableNames = []
44for i in range(0, len(name_to_idx)):
45 benchmark = idx_to_name[i]
46 if min(baseline_times[benchmark]) > TIMING_ERROR * 10:
47 reliableNames.append(benchmark)
48
49# Compute worst-case SMT slowdown for each benchmark
50print("Bench Mi")
51# Print rows
52sample_f = np.mean # Change this to np.mean to use mean values in Mi generation
53M_vals = []
54for b1 in reliableNames:
55 print("{:<14.14}:".format(b1), end=" ")
56 max_mi = 0
57 # Scan through everyone we ran against and find our maximum slowdown
58 for b2 in reliableNames:
59 time_with_smt = sample_f(paired_times[name_to_idx[b1]][name_to_idx[b2]])
60 time_wout_smt = sample_f(baseline_times[b1])
61 M = time_with_smt / time_wout_smt
62 max_mi = max(max_mi, M)
63 print("{:>10.3}".format(max_mi), end=" ")
64 M_vals.append(max_mi)
65 print("")
66# Print some statistics about the distribution
67print("Average: {:>5.3} with standard deviation {:>5.3} using `{}`".format(np.mean(M_vals), np.std(M_vals), sample_f.__name__))
68Ms = np.asarray(M_vals, dtype=np.float32)
69print(np.sum(Ms <= 1), "of", len(M_vals), "M_i values are at most one -", 100*np.sum(Ms <= 1)/len(M_vals), "percent")
70print(np.sum(Ms > 2), "of", len(M_vals), "M_i values are greater than two -", 100*np.sum(Ms > 2)/len(M_vals), "percent")
71M_vals_to_plot = Ms
72
73print(plt.hist(M_vals_to_plot, bins=10))
diff --git a/smt_analysis/computeSMTslowdown.py b/smt_analysis/computeSMTslowdown.py
index aa7aa21..805def1 100755
--- a/smt_analysis/computeSMTslowdown.py
+++ b/smt_analysis/computeSMTslowdown.py
@@ -3,19 +3,19 @@ from typing import List, Any
3import numpy as np 3import numpy as np
4from scipy import stats 4from scipy import stats
5import sys 5import sys
6import os
7import plotille.plotille as plt 6import plotille.plotille as plt
8TIMING_ERROR = 1000 #ns 7TIMING_ERROR = 1000 #ns
9LEVEL_C_ANALYSIS = False 8LEVEL_C_ANALYSIS = False
9from libSMT import *
10 10
11def print_usage(argv): 11def print_usage():
12 print("This program takes in the all-pairs and baseline SMT data and computes how much each program is slowed when SMT in enabled.", file=sys.stderr) 12 print("This program takes in the all-pairs and baseline SMT data and computes how much each program is slowed when SMT in enabled.", file=sys.stderr)
13 print("Level-A/B usage: {} <file -A> <file -B> <baseline file> --cij".format(argv[0]), file=sys.stderr) 13 print("Level-A/B usage: {} <file -A> <file -B> <baseline file> --cij".format(sys.argv[0]), file=sys.stderr)
14 print("Level-C usage: {} <continuous pairs> <baseline file>".format(argv[0]), file=sys.stderr) 14 print("Level-C usage: {} <continuous pairs> <baseline file>".format(sys.argv[0]), file=sys.stderr)
15 15
16# Check that we got the right number of parameters 16# Check that we got the right number of parameters
17if len(sys.argv) < 3: 17if len(sys.argv) < 3:
18 print_usage(sys.argv) 18 print_usage()
19 exit() 19 exit()
20 20
21if len(sys.argv) > 3: 21if len(sys.argv) > 3:
@@ -24,127 +24,12 @@ else:
24 print("Analyzing results using Level-C methodology...") 24 print("Analyzing results using Level-C methodology...")
25 LEVEL_C_ANALYSIS = True 25 LEVEL_C_ANALYSIS = True
26 26
27# Check that all input files are valid 27assert_valid_input_files(sys.argv[1:-1], print_usage);
28for f in sys.argv[1:-1]:
29 if not os.path.exists(f) or os.path.getsize(f) == 0:
30 print("ERROR: File '{}' does not exist or is empty".format(f), file=sys.stderr);
31 print_usage(sys.argv)
32 exit()
33 28
34# Print Cij values rather than Mij 29# Print Cij values rather than Mij
35TIMES_ONLY = len(sys.argv) > 4 and "--cij" in sys.argv[4] 30TIMES_ONLY = len(sys.argv) > 4 and "--cij" in sys.argv[4]
36OK_PAIRS_ONLY = len(sys.argv) > 4 and "--cij-ok" in sys.argv[4] 31OK_PAIRS_ONLY = len(sys.argv) > 4 and "--cij-ok" in sys.argv[4]
37 32
38# This parses the result data from unthreaded timing experiments
39# @param f File name to load
40# @returns res Map of benchmark name to sample count
41# @returns samples Map of benchmark name to list of execution time samples
42# @returns max_res May of benchmark to maximum execution time among all samples for that benchmark
43def load_baseline(f):
44 # constants for columns of baseline data files
45 TOTAL_NS = 5
46 BENCH_NAME = 0
47 SAMPLES = 4
48
49 # Load baseline data. This logic is based off the summarize programs
50 res = {} # Map of benchmark to list of all execution time samples
51 samples = {} # Map of benchmark name to sample count
52 max_res = {} # Map of benchmark name to maximum execution time
53
54 with open(f) as fp:
55 for line in fp:
56 s = line.split()
57 if s[BENCH_NAME] not in res:
58 res[s[BENCH_NAME]] = list([int(s[TOTAL_NS])])
59 samples[s[BENCH_NAME]] = int(s[SAMPLES])
60 max_res[s[BENCH_NAME]] = int(s[TOTAL_NS])
61 else:
62 res[s[BENCH_NAME]].append(int(s[TOTAL_NS]))
63 max_res[s[BENCH_NAME]] = max(int(s[TOTAL_NS]), max_res[s[BENCH_NAME]])
64 return res, samples, max_res
65
66# This parses the result data from paired, threaded timing experiements
67# @param file1 The -A file name
68# @param file2 The -B file name
69# @returns time 2D array of benchmark IDs to list of total container execution times
70# @returns offset 2D array of benchmark IDs to list of differences between the start
71# of the first and the start of the second benchmark
72# @returns name_to_idx Map of benchmark names to benchmark IDs
73# @returns idx_to_name List which when indexed with benchmark ID will yield the benchmark name
74def load_paired(file1, file2, benchmarkCount):
75 # constants for columns of paired data files
76 FIRST_PROG = 0
77 SECOND_PROG = 1
78 FIRST_CORE = 2
79 SECOND_CORE = 3
80 TRIALS = 4
81 START_S = 5 # Start seconds
82 START_N = 6 # Start nanoseconds
83 END_S = 7 # End seconds
84 END_N = 8 # End nanoseconds
85 RUN_ID = 9
86 JOB_NUM = 10
87
88 with open(file1) as f1:
89 numJobs = int(f1.readline().split()[TRIALS])
90 assert numJobs > 0
91 assert benchmarkCount > 0
92
93 # Total times of each container
94 time=[[[0 for x in range(numJobs)]for y in range(benchmarkCount)]for z in range(benchmarkCount)]
95 # Difference in time between when the first and the second task start in the container
96 offset=[[[0 for x in range(numJobs)]for y in range(benchmarkCount)]for z in range(benchmarkCount)]
97
98 # Some aggregate counters that we update as we go along
99 avg_off = 0
100 avg_off_samp = 0
101
102 # Load paired data
103 bench1 = 0 # Index to what's the current first benchmark being examined
104 bench2 = 0 # Index to what's the current second benchmark being examined
105
106 name_to_idx = {}