diff --git a/README.md b/README.md index 86352e6..70937c2 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,4 @@ -# TLS - -### WolfSSL - -```bash -git clone https://github.com/wolfSSL/wolfssl --depth 1 -cd wolfssl -sh autogen.sh -./configure --enable-all --enable-all-crypto --disable-shared --prefix=/opt/wolfssl-rs/ -make -sudo make install -``` +# TLS Energy measurement ## Reproduce @@ -159,7 +148,7 @@ https://api.grid5000.fr/stable/sites/nancy/metrics?nodes=gros-69&metrics=bmc_nod ```bash python plots.py summary results/g5k/summary X results/pi3/summary pi3 results/i5/summary i5 results/core2/summary C2 -python plots.py log2 results/core2/impl C2 results/pi3/impls \$\\\\pi\$3 results/i5/impls i5 +python plots.py log2 results/core2/impls results/pi3/impls results/i5/impls python plots.py stab results/pi3/stability \$\\\\pi\$3 results/core2/stability C2 results/i5/stability i5 results/g5k/stability X ``` diff --git a/exp.py b/exp.py index 1956cb1..ea88ad6 100644 --- a/exp.py +++ b/exp.py @@ -131,9 +131,9 @@ CONFIGS = { True, ], "records": [ - #{ "filename": "wp2", "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": "wp2", "repeat": 10000, "time": 600, "reproduce": 1 }, + { "filename": "yt2-ads", "repeat": 10000, "time": 1200, "reproduce": 1 }, + { "filename": "yt2-ublock", "repeat": 10000, "time": 1200, "reproduce": 1 }, #{ "filename": "wp2", "repeat": 10000, "time": 300, "reproduce": 100 }, ], "repo_dir": "/home/tuxmain/reps/tlsbench", @@ -166,17 +166,17 @@ CONFIGS = { #"debug", ], "sides": [ - "client", + #"client", "server", ], "tls": [ - False, - #True, + #False, + True, ], "records": [ - { "filename": "wp2", "repeat": 10000, "time": 300, "reproduce": 3 }, - { "filename": "yt2-ads", "repeat": 10000, "time": 300, "reproduce": 3 }, - { "filename": "yt2-ublock", "repeat": 10000, "time": 300, "reproduce": 3 }, + #{ "filename": "wp2", "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": "test", "repeat": 1, "time": 10 }, #{ "filename": "wp2", "repeat": 10000, "time": 300, "reproduce": 100 }, ], @@ -348,13 +348,13 @@ CERT_SIGN_ALGS = [ "rsa2048", "rsa3072", "rsa4096", # widely used ] 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 #"graviola", # New crypto in Rust - #"openssl", # widely used + "openssl", # widely used #"openssl-static", - #"ring", # used in most Rust stuff - #"symcrypt", # Microsoft's crypto + "ring", # used in most Rust stuff + "symcrypt", # Microsoft's crypto ] # Symmetric ciphers # They also allow to choose the TLS version. @@ -785,6 +785,9 @@ def run_exp(config, only_record=None, idle=False, shutdown=False, debug=False): if idle: print("Measuring idle...") remote_bytes_in, remote_bytes_out = get_net_stat(ssh) + controller_bytes_in, controller_bytes_out = (0, 0) + if config["measure_both"]: + controller_bytes_in, controller_bytes_out = get_net_stat(None) energy = 0 energy_rapl = 0 if config["wattmeter"]: @@ -803,8 +806,13 @@ def run_exp(config, only_record=None, idle=False, shutdown=False, debug=False): if config["rapl"]: new_energy_rapl = get_rapl_energy(ssh, remote_path) new_remote_bytes_in, new_remote_bytes_out = get_net_stat(ssh) + new_controller_bytes_in, new_controller_bytes_out = (0, 0) + if config["measure_both"]: + new_controller_bytes_in, new_controller_bytes_out = get_net_stat(None) remote_bytes_in_diff = new_remote_bytes_in - remote_bytes_in remote_bytes_out_diff = new_remote_bytes_out - remote_bytes_out + controller_bytes_in_diff = new_controller_bytes_in - controller_bytes_in + controller_bytes_out_diff = new_controller_bytes_out - controller_bytes_out energy_diff = new_energy - energy energy_rapl_diff = new_energy_rapl - energy_rapl time_diff = end - start @@ -812,6 +820,9 @@ def run_exp(config, only_record=None, idle=False, shutdown=False, debug=False): try: with open(logfile_path, "a") as logfile: logfile.write(f"{target} idle - - - - - - - - - {start} {end} {time_diff} 0 {remote_bytes_in_diff} {remote_bytes_out_diff} {energy_diff} {energy_rapl_diff} -\n") + if config["measure_both"]: + controller_target = config["controller_target"] + logfile.write(f"{controller_target} idle - - - - - - - - - {start} {end} {time_diff} 0 {controller_bytes_in_diff} {controller_bytes_out_diff} 0 0 -\n") logfile.close() break except Exception as e: @@ -1098,6 +1109,7 @@ Run options: --idle Also measure when idle --shutdown Shutdown host and target when finished --debug Print netreplay's debug + -f JSON file to update config """.format( sig_algs = " ".join(CERT_SIGN_ALGS), configs = " ".join([i for i in CONFIGS]), @@ -1121,6 +1133,16 @@ Run options: update_certs(config) elif opt == "run": config = CONFIGS[sys.argv[2]] + + add_config_file = getargv("-f") + if add_config_file: + import json + f = open(add_config_file, "r") + j = json.load(f) + f.close() + for k in j: + config[k] = j[k] + if "--count" in sys.argv: exps = 0 for expname in config["experiments"]: diff --git a/g5kwatt.py b/g5kwatt.py index c94ac85..0a49dca 100644 --- a/g5kwatt.py +++ b/g5kwatt.py @@ -48,6 +48,9 @@ def insert_wh_into_logfile(path, site, user, psw): logs = [] records = {} for line in lines[1:]: + if line[0] in "#\n": + logs.append({"comment": line}) + continue cols = line.removesuffix("\n").split(" ") log = {} for col in range(len(cols)): @@ -61,6 +64,9 @@ def insert_wh_into_logfile(path, site, user, psw): outfile = open(path+"-wh", "w") outfile.write(lines[0]) for log in logs: + if "comment" in log: + outfile.write(log["comment"]) + continue line = "" for col in colnames: if line != "": @@ -97,7 +103,7 @@ def get_psw(): return psw def main(): - if len(sys.argv) < 5: + if len(sys.argv) < 4: print("Usage:") print("python g5watt.py ") exit(0) diff --git a/orchestrate.py b/orchestrate.py new file mode 100644 index 0000000..b500fd6 --- /dev/null +++ b/orchestrate.py @@ -0,0 +1,20 @@ +# Orchestrator for G5K +# Fill the IP addresses and config tweaks of your job. + +import json, socket + +# Enter all the numbers of the nodes of the job +nodes = [] + +# IP of the nodes ("n" is placeholder for the node number) +IP = "172.16.101.n" + +configs = [ + {} +] + +def orchestrate(): + pass + +if __name__ == "__main__": + orchestrate() diff --git a/plots.py b/plots.py index 87ad4c9..c9648fe 100644 --- a/plots.py +++ b/plots.py @@ -71,14 +71,23 @@ PRETTY_TABLE = { "wp2": "WP", "yt2-ads": "YT", "yt2-ublock": "YT+µ", + "paradoxe": "X", + "core2": "C2", } PRETTY_TABLE_GNUPLOT = { "pi3": "Pi", "wp2": "WP", "yt2-ads": "YT", "yt2-ublock": "YT+µ", + "paradoxe": "X", + "core2": "C2", + "i5": "i5", } +# "cluster-number" to "cluster" +def cluster_name(target): + return target[:target.find("-")] if "-" in target else target + def impl_title(impl): # Gnuplot does not escape underscores when generating tex return impl.replace("_", "-") @@ -231,7 +240,7 @@ def make_log_plot(logs, exp, criterion, side, obj, record, machine=None, version ciphers = {} impls = [] plain_line = None - idle_val = None + idle_val = {} conv_factor = 1.0 if obj == "energy": # Convert Wh to Ws @@ -239,12 +248,12 @@ def make_log_plot(logs, exp, criterion, side, obj, record, machine=None, version for log in logs: if log["exp"] == "idle": - idle_val = float(log[COL[obj]]) / float(log["time"]) * conv_factor + idle_val[log["target"]] = float(log[COL[obj]]) / float(log["time"]) * conv_factor if log["exp"] != exp or log["record"] != record: continue if log["side"] == side and log["tls"] == "0": n = float(log.get("n", "1000")) - plain_line = "plain {}".format((float(log[COL[obj]]) * conv_factor - idle_val * float(log["time"])) / n) + plain_line = "plain {}".format((float(log[COL[obj]]) * conv_factor[log["target"]] - idle_val[log["target"]] * float(log["time"])) / n) if plain_line == None: return @@ -258,11 +267,11 @@ def make_log_plot(logs, exp, criterion, side, obj, record, machine=None, version ver = VER_LABEL[log["cipher"]] if log[COL[criterion]]+"/"+ver not in ciphers: ciphers[log[COL[criterion]]+"/"+ver] = {} - ciphers[log[COL[criterion]]+"/"+ver][log["impl"]] = (float(log[COL[obj]]) * conv_factor - idle_val * float(log["time"])) / n + ciphers[log[COL[criterion]]+"/"+ver][log["impl"]] = (float(log[COL[obj]]) * conv_factor - idle_val[log["target"]] * float(log["time"])) / n else: if log[COL[criterion]] not in ciphers: ciphers[log[COL[criterion]]] = {} - ciphers[log[COL[criterion]]][log["impl"]] = (float(log[COL[obj]]) * conv_factor - idle_val * float(log["time"])) / n + ciphers[log[COL[criterion]]][log["impl"]] = (float(log[COL[obj]]) * conv_factor - idle_val[log["target"]] * float(log["time"])) / n if log["impl"] not in impls: impls.append(log["impl"]) impls.sort() @@ -304,50 +313,50 @@ def make_log_plot(logs, exp, criterion, side, obj, record, machine=None, version maketitle=maketitle ) -def make_log_plot_points(logs_by_target, exp, criterion, side, obj, record, version=None): +def make_log_plot_points(logs, exp, criterion, side, obj, record, version=None): f = open(f"/dev/shm/plots/{obj}_by_{criterion}_{side}_{record}.dat", "w") - ciphers = {target: {} for target in logs_by_target} + ciphers = {} impls = [] - plain = {target: None for target in logs_by_target} - idle_val = {target: None for target in logs_by_target} + plain = {} + idle_val = {} conv_factor = 1.0 if obj == "energy": # Convert Wh to Ws conv_factor = 3600.0 - for target in logs_by_target: - logs = logs_by_target[target] - for log in logs: - if log["exp"] == "idle": - idle_val[target] = float(log[COL[obj]]) / float(log["time"]) * conv_factor - if log["exp"] != exp or log["record"] != record: - continue - if log["side"] == side and log["tls"] == "0": - n = float(log.get("n", "1000")) - plain[target] = (float(log[COL[obj]]) * conv_factor - idle_val[target] * float(log["time"])) / n + for log in logs: + if log["target"] not in ciphers: + ciphers[log["target"]] = {} + plain[log["target"]] = None + idle_val[log["target"]] = None + if log["exp"] == "idle": + idle_val[log["target"]] = float(log[COL[obj]]) / float(log["time"]) * conv_factor + if log["exp"] != exp or log["record"] != record: + continue + if log["side"] == side and log["tls"] == "0": + n = float(log.get("n", "1000")) + plain[log["target"]] = (float(log[COL[obj]]) * conv_factor - idle_val[log["target"]] * float(log["time"])) / n #for target in plain: # if plain[target] == None: # return - for target in logs_by_target: - logs = logs_by_target[target] - for log in logs: - if log["exp"] == exp and log["record"] == record and log["side"] == side: - if version != None and VER_LABEL[log["cipher"]] != version: - continue - n = float(log.get("n", "1000")) - if version == None: - ver = VER_LABEL[log["cipher"]] - if log[COL[criterion]]+"/"+ver not in ciphers[target]: - ciphers[target][log[COL[criterion]]+"/"+ver] = {} - ciphers[target][log[COL[criterion]]+"/"+ver][log["impl"]] = (float(log[COL[obj]]) * conv_factor - idle_val[target] * float(log["time"])) / n - else: - if log[COL[criterion]] not in ciphers[target]: - ciphers[target][log[COL[criterion]]] = {} - ciphers[target][log[COL[criterion]]][log["impl"]] = (float(log[COL[obj]]) * conv_factor - idle_val[target] * float(log["time"])) / n - if log["impl"] not in impls: - impls.append(log["impl"]) + for log in logs: + if log["exp"] == exp and log["record"] == record and log["side"] == side: + if version != None and VER_LABEL[log["cipher"]] != version: + continue + n = float(log.get("n", "1000")) + if version == None: + ver = VER_LABEL[log["cipher"]] + if log[COL[criterion]]+"/"+ver not in ciphers[log["target"]]: + ciphers[log["target"]][log[COL[criterion]]+"/"+ver] = {} + ciphers[log["target"]][log[COL[criterion]]+"/"+ver][log["impl"]] = (float(log[COL[obj]]) * conv_factor - idle_val[log["target"]] * float(log["time"])) / n + else: + if log[COL[criterion]] not in ciphers[log["target"]]: + ciphers[log["target"]][log[COL[criterion]]] = {} + ciphers[log["target"]][log[COL[criterion]]][log["impl"]] = (float(log[COL[obj]]) * conv_factor - idle_val[log["target"]] * float(log["time"])) / n + if log["impl"] not in impls: + impls.append(log["impl"]) impls.sort() f.write("target fulltarget {} none {}\n".format(criterion, " ".join([impl_title(impl) for impl in impls]))) for target in plain: @@ -359,7 +368,7 @@ def make_log_plot_points(logs_by_target, exp, criterion, side, obj, record, vers cipher_parts = cipher.split("/") f.write("{} {} {}({}) {} {}\n".format( target, - ALG_LABEL[cipher_parts[0]]+"/"+target, + ALG_LABEL[cipher_parts[0]]+"/"+PRETTY_TABLE_GNUPLOT[target], ALG_LABEL[cipher_parts[0]], cipher_parts[1], plain[target], @@ -371,7 +380,7 @@ def make_log_plot_points(logs_by_target, exp, criterion, side, obj, record, vers else: f.write("{} {} {} {} {}\n".format( target, - ALG_LABEL[cipher]+"/"+target, + ALG_LABEL[cipher]+"/"+PRETTY_TABLE_GNUPLOT[target], ALG_LABEL[cipher], plain[target], " ".join([ @@ -541,30 +550,25 @@ def make_linear_regression(logs, cat="impl"): # Measure relative difference between TLS versions def cmp_versions_multitarget(logs, exps, criteria, objs): ciphers = {} - idle_val = {target: None for target in logs_by_target} + idle_val = {} - for target in logs_by_target: - logs = logs_by_target[target] - for log in logs: - log["target"] = target - log["io"] = int(log["bytes_in"]) + int(log["bytes_out"]) - if log["exp"] == "idle": - idle_val[target] = {obj:float(log[COL[obj]]) / float(log["time"]) for obj in objs} + for log in logs: + log["io"] = int(log["bytes_in"]) + int(log["bytes_out"]) + if log["exp"] == "idle": + idle_val[log["target"]] = {obj:float(log[COL[obj]]) / float(log["time"]) for obj in objs} - for target in logs_by_target: - logs = logs_by_target[target] - for log in logs: - if log["exp"] not in exps or log["tls"] == "0": - continue - ver = VER_LABEL[log["cipher"]] - if ver not in ciphers: - ciphers[ver] = {} - key = [target] - for criterion in criteria: - key.append(ALG_LABEL.get(log[COL[criterion]], log[COL[criterion]])) - key = "/".join(key) - if key not in ciphers[ver]: - ciphers[ver][key] = log + for log in logs: + if log["exp"] not in exps or log["tls"] == "0": + continue + ver = VER_LABEL[log["cipher"]] + if ver not in ciphers: + ciphers[ver] = {} + key = [log["target"]] + for criterion in criteria: + key.append(ALG_LABEL.get(log[COL[criterion]], log[COL[criterion]])) + key = "/".join(key) + if key not in ciphers[ver]: + ciphers[ver][key] = log diff_rel_max = {obj:0.0 for obj in objs} diff_rel_sum = {obj:0.0 for obj in objs} @@ -670,16 +674,16 @@ def tabulate(lines, separator=" ", endline="", ruler=True): return table def make_summary(logs): - plain_result_key = lambda log: (log["exp"], log["side"], log["record"]) - result_key = lambda log: (log["exp"], log["side"], log["record"], log["impl"], log["alg"], log["kex"], log["cipher"], log["ed"]) + plain_result_key = lambda log: (cluster_name(log["target"]), log["exp"], log["side"], log["record"]) + result_key = lambda log: (cluster_name(log["target"]), log["exp"], log["side"], log["record"], log["impl"], log["alg"], log["kex"], log["cipher"], log["ed"]) plain_results = {} results = {} - idle_val = None + idle_val = {} for log in logs: if log["exp"] == "idle": - idle_val = { + idle_val[log["target"]] = { "cpu": float(log["cpu"]) / float(log["time"]), "energy": float(log["Wh"]) / float(log["time"]) * 3600, "in": float(log["bytes_in"]) / float(log["time"]), @@ -688,20 +692,21 @@ def make_summary(logs): if log["tls"] == "0": n = float(log.get("n", "1000")) plain_results[plain_result_key(log)] = { - "cpu": (float(log["cpu"]) - idle_val["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, - "energy": (float(log["Wh"]) * 3600 - idle_val["energy"] * float(log["time"])) / n, - "in": (float(log["bytes_in"]) - idle_val["in"] * float(log["time"])) / n, - "out": (float(log["bytes_out"]) - idle_val["out"] * float(log["time"])) / n, + "energy": (float(log["Wh"]) * 3600 - idle_val[log["target"]]["energy"] * 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, } if log["exp"] != "idle" and log["tls"] == "1": n = float(log.get("n", "1000")) results[result_key(log)] = { - "cpu": (float(log["cpu"]) - idle_val["cpu"] * float(log["time"])) / n, + "target": log["target"], + "cpu": (float(log["cpu"]) - idle_val[log["target"]]["cpu"] * float(log["time"])) / n, "total_energy": float(log["Wh"]) * 3600 / n, - "energy": (float(log["Wh"]) * 3600 - idle_val["energy"] * float(log["time"])) / n, - "in": (float(log["bytes_in"]) - idle_val["in"] * float(log["time"])) / n, - "out": (float(log["bytes_out"]) - idle_val["out"] * float(log["time"])) / n, + "energy": (float(log["Wh"]) * 3600 - idle_val[log["target"]]["energy"] * 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, } lines = [[ @@ -718,10 +723,10 @@ def make_summary(logs): ]] for k in results: r = results[k] - p = plain_results[k[:3]] + p = plain_results[k[:4]] lines.append([ "/".join([str(i) for i in k]), - str(round(idle_val["energy"], 1)), + str(round(idle_val[r["target"]]["energy"], 1)), str(round(p["energy"], 1)), str(round(r["energy"], 1)), str(round(r["energy"] - p["energy"], 1)) + " (" + str(round((r["energy"] - p["energy"])/r["energy"]*100, 1)) + "%)", @@ -734,16 +739,16 @@ def make_summary(logs): print(tabulate(lines)) def analyze_logs(logs): - plain_result_key = lambda log: (log["exp"], log["side"], log["record"]) - result_key = lambda log: (log["exp"], log["side"], log["record"], log["impl"], log["alg"], log["kex"], log["cipher"], log["ed"]) + plain_result_key = lambda log: (log["target"], log["exp"], log["side"], log["record"]) + result_key = lambda log: (log["target"], log["exp"], log["side"], log["record"], log["impl"], log["alg"], log["kex"], log["cipher"], log["ed"]) plain_results = {} results = {} - idle_val = None + idle_val = {} for log in logs: if log["exp"] == "idle": - idle_val = { + idle_val[log["target"]] = { "cpu": float(log["cpu"]) / float(log["time"]), "energy": float(log["Wh"]) / float(log["time"]) * 3600, "in": float(log["bytes_in"]) / float(log["time"]), @@ -752,15 +757,17 @@ def analyze_logs(logs): if log["tls"] == "0": n = float(log.get("n", "1000")) plain_results[plain_result_key(log)] = { - "cpu": (float(log["cpu"]) - idle_val["cpu"] * float(log["time"])) / n, + "target": log["target"], + "cpu": (float(log["cpu"]) - idle_val[log["target"]]["cpu"] * float(log["time"])) / n, "total_energy": float(log["Wh"]) * 3600 / n, - "energy": (float(log["Wh"]) * 3600 - idle_val["energy"] * float(log["time"])) / n, - "in": (float(log["bytes_in"]) - idle_val["in"] * float(log["time"])) / n, - "out": (float(log["bytes_out"]) - idle_val["out"] * float(log["time"])) / n, + "energy": (float(log["Wh"]) * 3600 - idle_val[log["target"]]["energy"] * 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, } if log["exp"] != "idle" and log["tls"] == "1": n = float(log.get("n", "1000")) results[result_key(log)] = { + "target": log["target"], "exp": log["exp"], "side": log["side"], "record": log["record"], @@ -769,18 +776,19 @@ def analyze_logs(logs): "kex": log["kex"], "cipher": log["cipher"], "ed": log["ed"], - "cpu": (float(log["cpu"]) - idle_val["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, - "energy": (float(log["Wh"]) * 3600 - idle_val["energy"] * float(log["time"])) / n, - "in": (float(log["bytes_in"]) - idle_val["in"] * float(log["time"])) / n, - "out": (float(log["bytes_out"]) - idle_val["out"] * float(log["time"])) / n, + "energy": (float(log["Wh"]) * 3600 - idle_val[log["target"]]["energy"] * 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, } lines = [] for k in results: r = results[k] - p = plain_results[k[:3]] + p = plain_results[k[:4]] lines.append({ + "target": r["target"], "exp": r["exp"], "side": r["side"], "record": r["record"], @@ -848,16 +856,16 @@ def average_items(items, to_average, target=None): return avg def analyze_average_logs(logs, target=None): - plain_result_key = lambda log: (log["exp"], log["side"], log["record"]) - result_key = lambda log: (log["exp"], log["side"], log["record"], log["impl"], log["alg"], log["kex"], log["cipher"], log["ed"]) + plain_result_key = lambda log: (cluster_name(log["target"]), log["exp"], log["side"], log["record"]) + result_key = lambda log: (cluster_name(log["target"]), log["exp"], log["side"], log["record"], log["impl"], log["alg"], log["kex"], log["cipher"], log["ed"]) plain_results = {} results = {} - idle_val = None + idle_val = {} for log in logs: if log["exp"] == "idle": - idle_val = { + idle_val[log["target"]] = { "cpu": float(log["cpu"]) / float(log["time"]), "energy": float(log["Wh"]) / float(log["time"]) * 3600, "in": float(log["bytes_in"]) / float(log["time"]), @@ -868,17 +876,20 @@ def analyze_average_logs(logs, target=None): if plain_result_key(log) not in plain_results: plain_results[plain_result_key(log)] = [] plain_results[plain_result_key(log)].append({ - "cpu": (float(log["cpu"]) - idle_val["cpu"] * float(log["time"])) / n, + "target": log["target"], + "cpu": (float(log["cpu"]) - idle_val[log["target"]]["cpu"] * float(log["time"])) / n, "total_energy": float(log["Wh"]) * 3600 / n, - "energy": (float(log["Wh"]) * 3600 - idle_val["energy"] * float(log["time"])) / n, - "in": (float(log["bytes_in"]) - idle_val["in"] * float(log["time"])) / n, - "out": (float(log["bytes_out"]) - idle_val["out"] * float(log["time"])) / n, + "energy": (float(log["Wh"]) * 3600 - idle_val[log["target"]]["energy"] * 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, + "cpu": float(log["cpu"]) / n, }) if log["exp"] != "idle" and log["tls"] == "1": n = float(log.get("n", "1000")) if result_key(log) not in results: results[result_key(log)] = [] results[result_key(log)].append({ + "target": log["target"], "exp": log["exp"], "side": log["side"], "record": log["record"], @@ -887,12 +898,12 @@ def analyze_average_logs(logs, target=None): "kex": log["kex"], "cipher": log["cipher"], "ed": log["ed"], - "idle": idle_val["energy"], - "cpu": (float(log["cpu"]) - idle_val["cpu"] * float(log["time"])) / n, + "idle": idle_val[log["target"]]["energy"], + "cpu": float(log["cpu"]) / n, "total_energy": float(log["Wh"]) * 3600 / n, - "energy": (float(log["Wh"]) * 3600 - idle_val["energy"] * float(log["time"])) / n, - "in": (float(log["bytes_in"]) - idle_val["in"] * float(log["time"])) / n, - "out": (float(log["bytes_out"]) - idle_val["out"] * float(log["time"])) / n, + "energy": (float(log["Wh"]) * 3600 - idle_val[log["target"]]["energy"] * 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, }) for key in plain_results: @@ -903,8 +914,9 @@ def analyze_average_logs(logs, target=None): lines = [] for k in results: r = results[k] - p = plain_results[k[:3]] + p = plain_results[k[:4]] lines.append({ + "target": r["target"], "exp": r["exp"], "side": r["side"], "record": r["record"], @@ -1121,65 +1133,84 @@ def make_tx_plot(logs_by_target, server_target): ]) print(tabulate(latex, separator=" & ", endline="\\\\ \\cline{3-9}", ruler=False)) -def make_summary_plot(logs_by_target): - lines = [["exp", "record", "alg", "kex", "cipher", "ed", "side", "target", "impl", "plain E (J/S)", "TLS E (J/S)", "TLS only E (J/S)", "plain io (o/S)", "TLS io (o/S)", "TLS only io (o/S)", "TLS E rel", "TLS io rel"]] +def make_summary_plot(logs): + lines = [["exp", "record", "alg", "kex", "cipher", "ed", "side", "target", "impl", "plain E (J/S)", "TLS E (J/S)", "TLS only E (J/S)", "plain io (o/S)", "TLS io (o/S)", "TLS only io (o/S)", "TLS E rel", "TLS io rel", "CPU rel"]] results = [] - for target in logs_by_target: - logs = logs_by_target[target] - target_results = analyze_average_logs(logs, target=target) - for log in target_results: - plain_energy = log["plain"]["energy"] - tls_energy = log["tls"]["energy"] - tls_only_energy = tls_energy - plain_energy - tls_rel_energy = tls_only_energy / plain_energy - plain_io = log["plain"]["in"] + log["plain"]["out"] - tls_io = log["tls"]["in"] + log["tls"]["out"] - tls_only_io = tls_io - plain_io - tls_rel_io = tls_only_io / plain_io - results.append({ - "target": target, - "exp": log["exp"], - "record": log["record"], - "alg": log["alg"], - "kex": log["kex"], - "cipher": log["cipher"], - "ed": log["ed"], - "version": VER_LABEL[log["cipher"]], - "impl": log["impl"], - "side": log["side"], - "tls": log["tls"], - "idle_energy": log["idle"], - "plain_energy": plain_energy, - "tls_energy": tls_energy, - "tls_only_energy": tls_only_energy, - "plain_io": plain_io, - "tls_io": tls_io, - "tls_only_io": tls_only_io, - "tls_rel_energy": tls_rel_energy, - "tls_rel_io": tls_rel_io, - }) - lines.append([ - log["exp"], - log["record"], - log["alg"], - log["kex"], - log["cipher"], - log["ed"], - log["side"], - target, - log["impl"], - str(round(plain_energy, 2)), - str(round(tls_energy, 2)), - str(round(tls_only_energy, 2)), - str(round(plain_io, 2)), - str(round(tls_io, 2)), - str(round(tls_only_io, 2)), - str(round(tls_rel_energy*100, 2))+"%", - str(round(tls_rel_io*100, 2))+"%", - ]) + target_results = analyze_average_logs(logs) + for log in target_results: + plain_energy = log["plain"]["energy"] + tls_energy = log["tls"]["energy"] + tls_only_energy = tls_energy - plain_energy + tls_rel_energy = tls_only_energy / plain_energy + plain_io = log["plain"]["in"] + log["plain"]["out"] + tls_io = log["tls"]["in"] + log["tls"]["out"] + tls_only_io = tls_io - plain_io + tls_rel_io = tls_only_io / plain_io + plain_cpu = log["plain"]["cpu"] + tls_cpu = log["tls"]["cpu"] + tls_only_cpu = tls_cpu - plain_cpu + results.append({ + "target": log["target"], + "exp": log["exp"], + "record": log["record"], + "alg": log["alg"], + "kex": log["kex"], + "cipher": log["cipher"], + "ed": log["ed"], + "version": VER_LABEL[log["cipher"]], + "impl": log["impl"], + "side": log["side"], + "tls": log["tls"], + "idle_energy": log["idle"], + "plain_energy": plain_energy, + "tls_energy": tls_energy, + "tls_only_energy": tls_only_energy, + "plain_io": plain_io, + "tls_io": tls_io, + "tls_only_io": tls_only_io, + "tls_rel_energy": tls_rel_energy, + "tls_rel_io": tls_rel_io, + "plain_cpu": plain_cpu, + "tls_cpu": tls_cpu, + "tls_only_cpu": tls_only_cpu, + }) + lines.append([ + log["exp"], + log["record"], + log["alg"], + log["kex"], + log["cipher"], + log["ed"], + log["side"], + log["target"], + log["impl"], + str(round(plain_energy, 2)), + str(round(tls_energy, 2)), + str(round(tls_only_energy, 2)), + str(round(plain_io, 2)), + str(round(tls_io, 2)), + str(round(tls_only_io, 2)), + str(round(tls_rel_energy*100, 2))+"%", + str(round(tls_rel_io*100, 2))+"%", + (str(round(tls_only_cpu / plain_cpu * 100, 2))+"%") if plain_cpu != 0 else "-", + ]) print(tabulate(lines)) print() + avg_cluster_idle = {} + for log in results: + target = cluster_name(log["target"]) + if target not in avg_cluster_idle: + avg_cluster_idle[target] = {} + avg_cluster_idle[target][log["idle_energy"]] = 1 + for target in avg_cluster_idle: + avg = 0 + nb = 0 + for val in avg_cluster_idle[target]: + avg += val + nb += 1 + avg_cluster_idle[target]["avg"] = avg / nb + print("\ \\multicolumn{1}{|c|}{\\multirow{2}*{\\textbf{Target}}}&\ \\multicolumn{1}{|c|}{\\multirow{2}*{\\textbf{Idle (W)}}}&\ @@ -1192,13 +1223,13 @@ def make_summary_plot(logs_by_target): latex_lines = {} latex_keys = [] for log in results: - key = (log["target"], log["record"], log["side"]) + key = (cluster_name(log["target"]), log["record"], log["side"]) if key in latex_lines: continue latex_keys.append(key) latex_lines[key] = [ - PRETTY_TABLE.get(log["target"], log["target"]), - "${}$".format(roundz(log["idle_energy"], 2)), + PRETTY_TABLE.get(cluster_name(log["target"]), cluster_name(log["target"])), + "${}$".format(roundz(avg_cluster_idle[cluster_name(log["target"])]["avg"], 2)), PRETTY_TABLE[log["record"]], log["side"], "${}$".format(roundz(log["plain_energy"], 2)), @@ -1297,6 +1328,8 @@ def make_summary_plot(logs_by_target): samples_energy_server = [] samples_io = [] for log_new in results: + if "paradoxe" in log_new["target"]: + continue ok = True for filter in cmp["new"]: if log_new[filter] != cmp["new"][filter]: @@ -1304,7 +1337,7 @@ def make_summary_plot(logs_by_target): break if not ok: continue - key_new = (log_new["exp"], log_new["target"], log_new["impl"], log_new["record"], log_new["side"]) + key_new = (log_new["exp"], cluster_name(log_new["target"]), log_new["impl"], log_new["record"], log_new["side"]) for log_old in results: ok = True for filter in cmp["old"]: @@ -1313,7 +1346,7 @@ def make_summary_plot(logs_by_target): break if not ok: continue - key_old = (log_old["exp"], log_old["target"], log_old["impl"], log_old["record"], log_old["side"]) + key_old = (log_old["exp"], cluster_name(log_old["target"]), log_old["impl"], log_old["record"], log_old["side"]) if key_new == key_old: if log_new["side"] == "server": samples_energy_server.append((log_new["tls_energy"] / log_old["tls_energy"] - 1.0) * 100.0) @@ -1339,10 +1372,8 @@ def make_summary_plot(logs_by_target): f_energy = open("/dev/shm/plots/energy-global.dat", "w") f_io = open("/dev/shm/plots/io-global.dat", "w") for log in results: - if log["target"] == "pi3" and "yt" in log["record"]: - continue - f_energy.write("{}-{} {}\n".format(PRETTY_TABLE_GNUPLOT.get(log["target"], log["target"]), log["side"], log["tls_rel_energy"] * 100.0)) - f_io.write("{}-{} {}\n".format(PRETTY_TABLE_GNUPLOT.get(log["target"], log["target"]), log["side"], log["tls_rel_io"] * 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)) + f_io.write("{}-{} {}\n".format(PRETTY_TABLE_GNUPLOT.get(cluster_name(log["target"]), log["target"]), log["side"], log["tls_rel_io"] * 100.0)) f_energy.close() f_io.close() @@ -1357,31 +1388,27 @@ def compute_box_plot(a): def make_stability_plot(logs_by_target): f = open(f"/dev/shm/plots/stability.dat", "w") - idle_val = {target: None for target in logs_by_target} + idle_val = {} - for target in logs_by_target: - logs = logs_by_target[target] - for log in logs: - if log["exp"] == "idle": - idle_val[target] = { - "energy": float(log[COL["energy"]]) / float(log["time"]) * 3600.0, - "io": float(log["bytes_in"])+float(log["bytes_out"]) / float(log["time"]), - } + for log in logs: + if log["exp"] == "idle": + idle_val[log["target"]] = { + "energy": float(log[COL["energy"]]) / float(log["time"]) * 3600.0, + "io": float(log["bytes_in"])+float(log["bytes_out"]) / float(log["time"]), + } all_results = {} - for target in logs_by_target: - logs = logs_by_target[target] - for log in logs: - if log["exp"] == "idle": - continue - n = float(log.get("n", "1000")) - key = "{}-{}".format(target, log["side"]) - if key not in all_results: - all_results[key] = [] - all_results[key].append({ - "energy": (float(log[COL["energy"]]) * 3600.0 - idle_val[target]["energy"] * float(log["time"])) / n, - "io": (float(log["bytes_in"])+float(log["bytes_out"]) - idle_val[target]["io"] * float(log["time"])) / n / 1024**2 - }) + for log in logs: + if log["exp"] == "idle": + continue + n = float(log.get("n", "1000")) + key = "{}-{}".format(PRETTY_TABLE_GNUPLOT[cluster_name(log["target"])], log["side"]) + if key not in all_results: + all_results[key] = [] + all_results[key].append({ + "energy": (float(log[COL["energy"]]) * 3600.0 - idle_val[log["target"]]["energy"] * float(log["time"])) / n, + "io": (float(log["bytes_in"])+float(log["bytes_out"]) - idle_val[log["target"]]["io"] * float(log["time"])) / n / 1024**2 + }) means = {key: { "energy": sum([i["energy"] for i in all_results[key]])/len(all_results[key]), @@ -1429,6 +1456,8 @@ def parse_logs(logfile_name): logs = [] records = {} for line in lines[1:]: + if line[0] in "#\n": + continue cols = line.removesuffix("\n").split(" ") log = {} for col in range(len(cols)): @@ -1465,24 +1494,22 @@ if __name__ == "__main__": make_log_plot(logs, "zrtt", "ed", side, "energy", record, machine=machine, maketitle=maketitle, version="1.3") cmp_versions(logs, ["impl-cipher-ver", "impl-cert-ver", "impl-kex-ver"], ["side", "cipher", "cert", "kex", "record"], ["cpu", "energy"]) elif cmd == "log2": - # Args: log2 [ ] [...] + # Args: log2 [] [...] # Only use the intersection of the records - logs_by_target = {sys.argv[3]: logs} records_to_remove = {} - for i in range(4, len(sys.argv), 2): + for i in range(3, len(sys.argv)): logs_i, records_i = parse_logs(sys.argv[i]) for record in records: if record not in records_i: records_to_remove[record] = () - target_i = sys.argv[i+1] - logs_by_target[target_i] = logs_i + logs += logs_i for record in records_to_remove: records.pop(record) for side in ["client", "server"]: for record in records: - make_log_plot_points(logs_by_target, "impl-cipher-ver", "cipher", side, "energy", record, version="1.3") - make_log_plot_points(logs_by_target, "impl-cert-ver", "cert", side, "energy", record, version="1.3") - make_log_plot_points(logs_by_target, "impl-kex-ver", "kex", side, "energy", record, version="1.3") + make_log_plot_points(logs, "impl-cipher-ver", "cipher", side, "energy", record, version="1.3") + make_log_plot_points(logs, "impl-cert-ver", "cert", side, "energy", record, version="1.3") + make_log_plot_points(logs, "impl-kex-ver", "kex", side, "energy", record, version="1.3") cmp_versions_multitarget(logs, ["impl-cipher-ver", "impl-cert-ver", "impl-kex-ver"], ["side", "cipher", "cert", "kex", "record", "ed", "impl"], ["energy", "io"]) elif cmd == "prof": for side in ["client", "server"]: @@ -1494,15 +1521,11 @@ if __name__ == "__main__": make_profile_plot_grouped(logs, "impl-cert-ver", "cert", side, record, "impl", no_flamegraph=no_flamegraph, machine=machine, maketitle=maketitle, version="1.3") make_profile_plot_grouped(logs, "impl-kex-ver", "kex", side, record, "impl", no_flamegraph=no_flamegraph, machine=machine, maketitle=maketitle, version="1.3") elif cmd == "summary": - # Args: stab [ ] [...] - # First target is the server - server = sys.argv[3] - logs_by_target = {server: logs} - for i in range(4, len(sys.argv), 2): + # Args: stab [] [...] + for i in range(3, len(sys.argv)): logs_i, records_i = parse_logs(sys.argv[i]) - target_i = sys.argv[i+1] - logs_by_target[target_i] = logs_i - make_summary_plot(logs_by_target) + logs += logs_i + make_summary_plot(logs) elif cmd == "tx": # Args: stab [ ] [...] # First target is the server @@ -1519,10 +1542,8 @@ if __name__ == "__main__": import numpy as np make_linear_regression(logs, "alg") elif cmd == "stab": - # Args: stab [ ] [...] - logs_by_target = {sys.argv[3]: logs} - for i in range(4, len(sys.argv), 2): + # Args: stab [] [...] + for i in range(3, len(sys.argv)): logs_i, records_i = parse_logs(sys.argv[i]) - target_i = sys.argv[i+1] - logs_by_target[target_i] = logs_i - make_stability_plot(logs_by_target) + logs += logs_i + make_stability_plot(logs)