Better global plots
This commit is contained in:
parent
6272ed193b
commit
da9593860d
2 changed files with 104 additions and 30 deletions
47
exp.py
47
exp.py
|
|
@ -137,7 +137,13 @@ CONFIGS = {
|
||||||
#{ "filename": "wp2", "repeat": 10000, "time": 300, "reproduce": 100 },
|
#{ "filename": "wp2", "repeat": 10000, "time": 300, "reproduce": 100 },
|
||||||
#{ "filename": "guardian", "realistic": True, "repeat": 10000, "time": 60, "reproduce": 1 },
|
#{ "filename": "guardian", "realistic": True, "repeat": 10000, "time": 60, "reproduce": 1 },
|
||||||
#{ "filename": "wikipedia", "realistic": True, "repeat": 10000, "time": 120, "reproduce": 10 },
|
#{ "filename": "wikipedia", "realistic": True, "repeat": 10000, "time": 120, "reproduce": 10 },
|
||||||
{ "filename": "zimbra", "realistic": True, "repeat": 10000, "time": 60, "reproduce": 10 },
|
#{ "filename": "zimbra", "realistic": True, "repeat": 10000, "time": 60, "reproduce": 10 },
|
||||||
|
#{ "filename": "reddit", "realistic": True, "repeat": 10000, "time": 120, "reproduce": 10 },
|
||||||
|
#{ "filename": "amazon", "realistic": True, "repeat": 10000, "time": 120, "reproduce": 10 },
|
||||||
|
{ "filename": "instagram", "realistic": True, "repeat": 10000, "time": 120, "reproduce": 10 },
|
||||||
|
{ "filename": "yt", "realistic": True, "repeat": 10000, "time": 120, "reproduce": 10 },
|
||||||
|
{ "filename": "yt-ublock", "realistic": True, "repeat": 10000, "time": 120, "reproduce": 10 },
|
||||||
|
{ "filename": "guardian-ublock", "realistic": True, "repeat": 10000, "time": 120, "reproduce": 10 },
|
||||||
],
|
],
|
||||||
"repo_dir": "/home/tuxmain/reps/tlsbench",
|
"repo_dir": "/home/tuxmain/reps/tlsbench",
|
||||||
"exp_dir": "/dev/shm/exp",
|
"exp_dir": "/dev/shm/exp",
|
||||||
|
|
@ -169,19 +175,22 @@ CONFIGS = {
|
||||||
#"debug",
|
#"debug",
|
||||||
],
|
],
|
||||||
"sides": [
|
"sides": [
|
||||||
#"client",
|
"client",
|
||||||
"server",
|
"server",
|
||||||
],
|
],
|
||||||
"tls": [
|
"tls": [
|
||||||
#False,
|
False,
|
||||||
True,
|
True,
|
||||||
],
|
],
|
||||||
"records": [
|
"records": [
|
||||||
#{ "filename": "wp2", "repeat": 10000, "time": 600, "reproduce": 1 },
|
#{ "filename": "wp2", "repeat": 10000, "time": 600, "reproduce": 1 },
|
||||||
{ "filename": "yt2-ads", "repeat": 10000, "time": 600, "reproduce": 1 },
|
#{ "filename": "yt2-ads", "repeat": 10000, "time": 600, "reproduce": 1 },
|
||||||
{ "filename": "yt2-ublock", "repeat": 10000, "time": 600, "reproduce": 1 },
|
#{ "filename": "yt2-ublock", "repeat": 10000, "time": 600, "reproduce": 1 },
|
||||||
#{ "filename": "test", "repeat": 1, "time": 10 },
|
#{ "filename": "test", "repeat": 1, "time": 10 },
|
||||||
#{ "filename": "wp2", "repeat": 10000, "time": 300, "reproduce": 100 },
|
#{ "filename": "wp2", "repeat": 10000, "time": 300, "reproduce": 100 },
|
||||||
|
#{ "filename": "wikipedia", "realistic": True, "repeat": 10000, "time": 60, "reproduce": 10 },
|
||||||
|
#{ "filename": "yt", "realistic": True, "repeat": 10000, "time": 120, "reproduce": 10 },
|
||||||
|
{ "filename": "amazon", "realistic": True, "repeat": 10000, "time": 120, "reproduce": 10 },
|
||||||
],
|
],
|
||||||
"repo_dir": "/home/tuxmain/reps/tlsbench",
|
"repo_dir": "/home/tuxmain/reps/tlsbench",
|
||||||
"exp_dir": "/dev/shm/exp",
|
"exp_dir": "/dev/shm/exp",
|
||||||
|
|
@ -216,14 +225,19 @@ CONFIGS = {
|
||||||
"server",
|
"server",
|
||||||
],
|
],
|
||||||
"tls": [
|
"tls": [
|
||||||
#False,
|
False,
|
||||||
True,
|
True,
|
||||||
],
|
],
|
||||||
"records": [
|
"records": [
|
||||||
{ "filename": "wp2", "repeat": 10000, "time": 300, "reproduce": 2 },
|
#{ "filename": "wp2", "repeat": 10000, "time": 300, "reproduce": 2 },
|
||||||
{ "filename": "yt2-ads", "repeat": 10000, "time": 300, "reproduce": 2 },
|
#{ "filename": "yt2-ads", "repeat": 10000, "time": 300, "reproduce": 2 },
|
||||||
{ "filename": "yt2-ublock", "repeat": 10000, "time": 300, "reproduce": 2 },
|
#{ "filename": "yt2-ublock", "repeat": 10000, "time": 300, "reproduce": 2 },
|
||||||
#{ "filename": "wp2", "repeat": 10000, "time": 300, "reproduce": 100 },
|
{ "filename": "yt-ublock", "realistic": True, "repeat": 10000, "time": 60, "reproduce": 10 },
|
||||||
|
{ "filename": "guardian", "realistic": True, "repeat": 10000, "time": 60, "reproduce": 10 },
|
||||||
|
{ "filename": "guardian-ublock", "realistic": True, "repeat": 10000, "time": 60, "reproduce": 10 },
|
||||||
|
{ "filename": "amazon", "realistic": True, "repeat": 10000, "time": 60, "reproduce": 10 },
|
||||||
|
{ "filename": "wikipedia", "realistic": True, "repeat": 10000, "time": 60, "reproduce": 10 },
|
||||||
|
{ "filename": "reddit", "realistic": True, "repeat": 10000, "time": 60, "reproduce": 10 },
|
||||||
],
|
],
|
||||||
"repo_dir": "/home/tuxmain/reps/tlsbench",
|
"repo_dir": "/home/tuxmain/reps/tlsbench",
|
||||||
"exp_dir": "/dev/shm/exp",
|
"exp_dir": "/dev/shm/exp",
|
||||||
|
|
@ -354,7 +368,7 @@ CERT_SIGN_ALGS = [
|
||||||
IMPLS = [
|
IMPLS = [
|
||||||
"aws-lc", # Amazon's crypto widely used in Rust stuff
|
"aws-lc", # Amazon's crypto widely used in Rust stuff
|
||||||
"boring", # Google's fork of OpenSSL used in Chrome and Android
|
"boring", # Google's fork of OpenSSL used in Chrome and Android
|
||||||
#"graviola", # New crypto in Rust
|
"graviola", # New crypto in Rust
|
||||||
"openssl", # widely used
|
"openssl", # widely used
|
||||||
#"openssl-static",
|
#"openssl-static",
|
||||||
"ring", # used in most Rust stuff
|
"ring", # used in most Rust stuff
|
||||||
|
|
@ -482,7 +496,10 @@ EXPERIMENTS = {
|
||||||
#"rsa4096",
|
#"rsa4096",
|
||||||
"realistic",
|
"realistic",
|
||||||
],
|
],
|
||||||
"earlydata": ["0", "1"],
|
"earlydata": [
|
||||||
|
"0",
|
||||||
|
"1"
|
||||||
|
],
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -684,7 +701,7 @@ def run_netreplay_client(
|
||||||
if skip_verif:
|
if skip_verif:
|
||||||
cmd.append("-s")
|
cmd.append("-s")
|
||||||
if concurrency != None:
|
if concurrency != None:
|
||||||
cmd += ["--concurrency", concurrency]
|
cmd += ["--concurrency", str(concurrency)]
|
||||||
cmdline = " ".join(cmd)
|
cmdline = " ".join(cmd)
|
||||||
#print(cmdline)
|
#print(cmdline)
|
||||||
return ssh_run_bg(ssh, cmdline, env)
|
return ssh_run_bg(ssh, cmdline, env)
|
||||||
|
|
@ -918,7 +935,7 @@ def run_exp(config, only_record=None, idle=False, shutdown=False, debug=False):
|
||||||
debug=debug,
|
debug=debug,
|
||||||
notify_addr=config["notify_addr"],
|
notify_addr=config["notify_addr"],
|
||||||
ld_preload=config["ld_preload"] if "ld_preload" in config else None,
|
ld_preload=config["ld_preload"] if "ld_preload" in config else None,
|
||||||
concurrency=config.get("concurrency"),
|
concurrency=record.get("concurrency", config.get("concurrency")),
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
netreplay = run_netreplay_server(
|
netreplay = run_netreplay_server(
|
||||||
|
|
@ -957,7 +974,7 @@ def run_exp(config, only_record=None, idle=False, shutdown=False, debug=False):
|
||||||
notify_addr=config["notify_addr"],
|
notify_addr=config["notify_addr"],
|
||||||
ld_preload=config["ld_preload"] if "ld_preload" in config else None,
|
ld_preload=config["ld_preload"] if "ld_preload" in config else None,
|
||||||
skip_verif=not config["measure_both"],
|
skip_verif=not config["measure_both"],
|
||||||
concurrency=config.get("concurrency"),
|
concurrency=record.get("concurrency", config.get("concurrency")),
|
||||||
)
|
)
|
||||||
|
|
||||||
prof_filename = "-"
|
prof_filename = "-"
|
||||||
|
|
|
||||||
87
plots.py
87
plots.py
|
|
@ -68,22 +68,53 @@ CRITERION_TITLE = {
|
||||||
}
|
}
|
||||||
PRETTY_TABLE = {
|
PRETTY_TABLE = {
|
||||||
"pi3": "Pi",
|
"pi3": "Pi",
|
||||||
|
"paradoxe": "X",
|
||||||
|
"core2": "C2",
|
||||||
|
|
||||||
"wp2": "WP",
|
"wp2": "WP",
|
||||||
"yt2-ads": "YT",
|
"yt2-ads": "YT",
|
||||||
"yt2-ublock": "YT+µ",
|
"yt2-ublock": "YT+µ",
|
||||||
"paradoxe": "X",
|
|
||||||
"core2": "C2",
|
"wikipedia": "Wikipedia",
|
||||||
|
"yt": "YouTube",
|
||||||
|
"yt-ublock": "YouTube+µ",
|
||||||
|
"guardian": "Guardian",
|
||||||
|
"guardian-ublock": "Guardian+µ",
|
||||||
|
"reddit": "Reddit",
|
||||||
|
"zimbra": "Zimbra",
|
||||||
|
"amazon": "Amazon",
|
||||||
|
"instagram": "Instagram",
|
||||||
}
|
}
|
||||||
PRETTY_TABLE_GNUPLOT = {
|
PRETTY_TABLE_GNUPLOT = {
|
||||||
"pi3": "Pi",
|
"pi3": "Pi",
|
||||||
"wp2": "WP",
|
|
||||||
"yt2-ads": "YT",
|
|
||||||
"yt2-ublock": "YT+µ",
|
|
||||||
"paradoxe": "X",
|
"paradoxe": "X",
|
||||||
"core2": "C2",
|
"core2": "C2",
|
||||||
"i5": "i5",
|
"i5": "i5",
|
||||||
|
|
||||||
|
"wp2": "WP",
|
||||||
|
"yt2-ads": "YT",
|
||||||
|
"yt2-ublock": "YT+µ",
|
||||||
|
|
||||||
|
"wikipedia": "Wikipedia",
|
||||||
|
"yt": "YouTube",
|
||||||
|
"yt-ublock": "YouTube+µ",
|
||||||
|
"guardian": "Guardian",
|
||||||
|
"guardian-ublock": "Guardian+µ",
|
||||||
|
"reddit": "Reddit",
|
||||||
|
"zimbra": "Zimbra",
|
||||||
|
"amazon": "Amazon",
|
||||||
|
"instagram": "Instagram",
|
||||||
|
|
||||||
|
"pq-ec": "PQ/EC",
|
||||||
|
"ec0rtt-ec": "0-RTT/EC",
|
||||||
|
"pq0rtt-pq": "0-RTT/PQ",
|
||||||
|
"pq0rtt-ec": "PQ+0-RTT/EC",
|
||||||
|
"13-12": "1.3/1.2",
|
||||||
|
"12-plain": "1.2/none",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FIX_POWER_TARGETS = ["paradoxe-40", "paradoxe-61", "paradoxe-62", "paradoxe-64"]
|
||||||
|
|
||||||
# "cluster-number" to "cluster"
|
# "cluster-number" to "cluster"
|
||||||
def cluster_name(target):
|
def cluster_name(target):
|
||||||
return target[:target.find("-")] if "-" in target else target
|
return target[:target.find("-")] if "-" in target else target
|
||||||
|
|
@ -864,10 +895,14 @@ def analyze_average_logs(logs, target=None):
|
||||||
idle_val = {}
|
idle_val = {}
|
||||||
|
|
||||||
for log in logs:
|
for log in logs:
|
||||||
|
fix_power_factor = 1
|
||||||
|
if log["target"] in FIX_POWER_TARGETS:
|
||||||
|
fix_power_factor = 2
|
||||||
|
|
||||||
if log["exp"] == "idle":
|
if log["exp"] == "idle":
|
||||||
idle_val[log["target"]] = {
|
idle_val[log["target"]] = {
|
||||||
"cpu": float(log["cpu"]) / float(log["time"]),
|
"cpu": float(log["cpu"]) / float(log["time"]),
|
||||||
"energy": float(log["Wh"]) / float(log["time"]) * 3600,
|
"energy": float(log["Wh"]) / float(log["time"]) * 3600 * fix_power_factor,
|
||||||
"in": float(log["bytes_in"]) / float(log["time"]),
|
"in": float(log["bytes_in"]) / float(log["time"]),
|
||||||
"out": float(log["bytes_out"]) / float(log["time"]),
|
"out": float(log["bytes_out"]) / float(log["time"]),
|
||||||
}
|
}
|
||||||
|
|
@ -878,8 +913,9 @@ def analyze_average_logs(logs, target=None):
|
||||||
plain_results[plain_result_key(log)].append({
|
plain_results[plain_result_key(log)].append({
|
||||||
"target": log["target"],
|
"target": log["target"],
|
||||||
"cpu": (float(log["cpu"]) - idle_val[log["target"]]["cpu"] * float(log["time"])) / n,
|
"cpu": (float(log["cpu"]) - idle_val[log["target"]]["cpu"] * float(log["time"])) / n,
|
||||||
"total_energy": float(log["Wh"]) * 3600 / n,
|
"total_energy": float(log["Wh"]) * 3600 / n * fix_power_factor,
|
||||||
"energy": (float(log["Wh"]) * 3600 - idle_val[log["target"]]["energy"] * float(log["time"])) / n,
|
"total_power": float(log["Wh"]) * 3600 / float(log["time"]) * fix_power_factor,
|
||||||
|
"energy": (float(log["Wh"]) * 3600 * fix_power_factor - idle_val[log["target"]]["energy"] * float(log["time"])) / n,
|
||||||
"in": (float(log["bytes_in"]) - idle_val[log["target"]]["in"] * float(log["time"])) / n,
|
"in": (float(log["bytes_in"]) - idle_val[log["target"]]["in"] * float(log["time"])) / n,
|
||||||
"out": (float(log["bytes_out"]) - idle_val[log["target"]]["out"] * float(log["time"])) / n,
|
"out": (float(log["bytes_out"]) - idle_val[log["target"]]["out"] * float(log["time"])) / n,
|
||||||
"cpu": float(log["cpu"]) / n,
|
"cpu": float(log["cpu"]) / n,
|
||||||
|
|
@ -900,8 +936,9 @@ def analyze_average_logs(logs, target=None):
|
||||||
"ed": log["ed"],
|
"ed": log["ed"],
|
||||||
"idle": idle_val[log["target"]]["energy"],
|
"idle": idle_val[log["target"]]["energy"],
|
||||||
"cpu": float(log["cpu"]) / n,
|
"cpu": float(log["cpu"]) / n,
|
||||||
"total_energy": float(log["Wh"]) * 3600 / n,
|
"total_energy": float(log["Wh"]) * 3600 / n * fix_power_factor,
|
||||||
"energy": (float(log["Wh"]) * 3600 - idle_val[log["target"]]["energy"] * float(log["time"])) / n,
|
"total_power": float(log["Wh"]) * 3600 / float(log["time"]) * fix_power_factor,
|
||||||
|
"energy": (float(log["Wh"]) * 3600 * fix_power_factor - idle_val[log["target"]]["energy"] * float(log["time"])) / n,
|
||||||
"in": (float(log["bytes_in"]) - idle_val[log["target"]]["in"] * float(log["time"])) / n,
|
"in": (float(log["bytes_in"]) - idle_val[log["target"]]["in"] * float(log["time"])) / n,
|
||||||
"out": (float(log["bytes_out"]) - idle_val[log["target"]]["out"] * float(log["time"])) / n,
|
"out": (float(log["bytes_out"]) - idle_val[log["target"]]["out"] * float(log["time"])) / n,
|
||||||
})
|
})
|
||||||
|
|
@ -1173,6 +1210,10 @@ def make_summary_plot(logs):
|
||||||
"plain_cpu": plain_cpu,
|
"plain_cpu": plain_cpu,
|
||||||
"tls_cpu": tls_cpu,
|
"tls_cpu": tls_cpu,
|
||||||
"tls_only_cpu": tls_only_cpu,
|
"tls_only_cpu": tls_only_cpu,
|
||||||
|
"plain_total_energy": log["plain"]["total_energy"],
|
||||||
|
"tls_total_energy": log["tls"]["total_energy"],
|
||||||
|
"plain_total_power": log["plain"]["total_power"],
|
||||||
|
"tls_total_power": log["tls"]["total_power"],
|
||||||
})
|
})
|
||||||
lines.append([
|
lines.append([
|
||||||
log["exp"],
|
log["exp"],
|
||||||
|
|
@ -1300,6 +1341,10 @@ def make_summary_plot(logs):
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
cmps = {
|
cmps = {
|
||||||
|
"13-12": {
|
||||||
|
"new": {"cipher": "AES_256_GCM_SHA384", "kex": "X25519", "ed": "0"},
|
||||||
|
"old": {"cipher": "ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,ECDHE_RSA_WITH_AES_256_GCM_SHA384", "kex": "X25519", "ed": "0"},
|
||||||
|
},
|
||||||
"pq-ec": {
|
"pq-ec": {
|
||||||
"new": {"cipher": "AES_256_GCM_SHA384", "kex": "X25519MLKEM768", "ed": "0"},
|
"new": {"cipher": "AES_256_GCM_SHA384", "kex": "X25519MLKEM768", "ed": "0"},
|
||||||
"old": {"cipher": "AES_256_GCM_SHA384", "kex": "X25519", "ed": "0"},
|
"old": {"cipher": "AES_256_GCM_SHA384", "kex": "X25519", "ed": "0"},
|
||||||
|
|
@ -1316,12 +1361,12 @@ def make_summary_plot(logs):
|
||||||
"new": {"cipher": "AES_256_GCM_SHA384", "kex": "X25519MLKEM768", "ed": "1"},
|
"new": {"cipher": "AES_256_GCM_SHA384", "kex": "X25519MLKEM768", "ed": "1"},
|
||||||
"old": {"cipher": "AES_256_GCM_SHA384", "kex": "X25519", "ed": "0"},
|
"old": {"cipher": "AES_256_GCM_SHA384", "kex": "X25519", "ed": "0"},
|
||||||
},
|
},
|
||||||
"13-12": {
|
|
||||||
"new": {"cipher": "AES_256_GCM_SHA384", "kex": "X25519", "ed": "0"},
|
|
||||||
"old": {"cipher": "ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,ECDHE_RSA_WITH_AES_256_GCM_SHA384", "kex": "X25519", "ed": "0"},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
f_all_cmp_client = open("/dev/shm/plots/cmp-client.dat", "w")
|
||||||
|
f_all_cmp_server = open("/dev/shm/plots/cmp-server.dat", "w")
|
||||||
|
f_all_cmp_io = open("/dev/shm/plots/cmp-io.dat", "w")
|
||||||
|
|
||||||
for cmp_name in cmps:
|
for cmp_name in cmps:
|
||||||
cmp = cmps[cmp_name]
|
cmp = cmps[cmp_name]
|
||||||
samples_energy_client = []
|
samples_energy_client = []
|
||||||
|
|
@ -1359,24 +1404,36 @@ def make_summary_plot(logs):
|
||||||
f = open(f"/dev/shm/plots/{cmp_name}-client.dat", "w")
|
f = open(f"/dev/shm/plots/{cmp_name}-client.dat", "w")
|
||||||
for sample in samples_energy_client:
|
for sample in samples_energy_client:
|
||||||
f.write(f"{sample}\n")
|
f.write(f"{sample}\n")
|
||||||
|
f_all_cmp_client.write("{} {}\n".format(PRETTY_TABLE_GNUPLOT[cmp_name], sample))
|
||||||
f.close()
|
f.close()
|
||||||
f = open(f"/dev/shm/plots/{cmp_name}-server.dat", "w")
|
f = open(f"/dev/shm/plots/{cmp_name}-server.dat", "w")
|
||||||
for sample in samples_energy_server:
|
for sample in samples_energy_server:
|
||||||
f.write(f"{sample}\n")
|
f.write(f"{sample}\n")
|
||||||
|
f_all_cmp_server.write("{} {}\n".format(PRETTY_TABLE_GNUPLOT[cmp_name], sample))
|
||||||
f.close()
|
f.close()
|
||||||
f = open(f"/dev/shm/plots/{cmp_name}-io.dat", "w")
|
f = open(f"/dev/shm/plots/{cmp_name}-io.dat", "w")
|
||||||
for sample in samples_io:
|
for sample in samples_io:
|
||||||
f.write(f"{sample}\n")
|
f.write(f"{sample}\n")
|
||||||
|
f_all_cmp_io.write("{} {}\n".format(PRETTY_TABLE_GNUPLOT[cmp_name], sample))
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
f_energy = open("/dev/shm/plots/energy-global.dat", "w")
|
f_energy = open("/dev/shm/plots/energy-global.dat", "w")
|
||||||
f_io = open("/dev/shm/plots/io-global.dat", "w")
|
f_io = open("/dev/shm/plots/io-global.dat", "w")
|
||||||
for log in results:
|
for log in results:
|
||||||
f_energy.write("{}-{} {}\n".format(PRETTY_TABLE_GNUPLOT.get(cluster_name(log["target"]), log["target"]), log["side"], log["tls_rel_energy"] * 100.0))
|
f_energy.write("{}-{} {} {}\n".format(PRETTY_TABLE_GNUPLOT.get(cluster_name(log["target"]), log["target"]), log["side"], log["tls_rel_energy"] * 100.0, log["tls_total_power"], log["plain_total_power"]))
|
||||||
f_io.write("{}-{} {}\n".format(PRETTY_TABLE_GNUPLOT.get(cluster_name(log["target"]), log["target"]), log["side"], log["tls_rel_io"] * 100.0))
|
f_io.write("{}-{} {}\n".format(PRETTY_TABLE_GNUPLOT.get(cluster_name(log["target"]), log["target"]), log["side"], log["tls_rel_io"] * 100.0))
|
||||||
|
#if log["side"] == "client":
|
||||||
|
# f_all_cmp_client.write("{} {}\n".format(PRETTY_TABLE_GNUPLOT["12-plain"], log["tls_rel_energy"] * 100.0))
|
||||||
|
#if log["side"] == "server":
|
||||||
|
# f_all_cmp_server.write("{} {}\n".format(PRETTY_TABLE_GNUPLOT["12-plain"], log["tls_rel_energy"] * 100.0))
|
||||||
|
f_all_cmp_io.write("{} {}\n".format(PRETTY_TABLE_GNUPLOT["12-plain"], log["tls_rel_io"] * 100.0))
|
||||||
f_energy.close()
|
f_energy.close()
|
||||||
f_io.close()
|
f_io.close()
|
||||||
|
|
||||||
|
f_all_cmp_client.close()
|
||||||
|
f_all_cmp_server.close()
|
||||||
|
f_all_cmp_io.close()
|
||||||
|
|
||||||
def compute_box_plot(a):
|
def compute_box_plot(a):
|
||||||
a.sort()
|
a.sort()
|
||||||
median = a[len(a)//2] if len(a)%2 == 1 else (a[len(a)//2-1]+a[len(a)//2])/2
|
median = a[len(a)//2] if len(a)%2 == 1 else (a[len(a)//2-1]+a[len(a)//2])/2
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue