diff --git a/exp.py b/exp.py index 8edc6d9..a725b46 100644 --- a/exp.py +++ b/exp.py @@ -2,6 +2,83 @@ import os, sys, subprocess, socket, signal CONFIGS = { + # This first config is a placeholder for documenting the available options. + # A config defines settings and values that will be tested in all possible combinations. + "choose_a_config_name": { + # List of the experiments to perform, in order. (they are defined in EXPERIMENTS below) + "experiments": [ + "impl-cipher-ver", + "impl-cert-ver", + "impl-kex-ver", + ], + # Run client and server on the target (what is being measured). + "sides": [ + "client", + "server", + ], + # Run without and with TLS + # Within an experiment, settings combinations that have no impact when TLS is not used (e.g. different ciphers) run only once. + "tls": [ + False, + True, + ], + # Traffic records to replay + # * filename: in the ./records folder + # * repeat: maximum number of times to replay the records (mostly useful to stop early in case of misconfiguration, best not to hit it) + # * time: number of seconds to run the experiment + # * reproduce: number of times to run the experiment + "records": [ + { "filename": "wp2", "repeat": 10000, "time": 120, "reproduce": 10 }, + ], + # Path to the repository on the controller machine + "repo_dir": "/home/pengelib/tlsbench", + # Path to temporary data on both machines (will be created automatically) + "exp_dir": "/dev/shm/exp", + # Directory where experiment logs (raw results) are stored + "log_backup_dir": "/home/pengelib", + # LAN address of the controller + "local_addr": "172.16.101.x", + # LAN address of the target + "remote_addr": "172.16.101.x", + # SSH user@host of the target (remove if target is in the same machine/user) + "remote_ssh": "pengelib@paradoxe-x", + # SSH password for the target (may be None) + "remote_psw": None, + # Path to this repository on the target + "remote_repo_dir": "/home/pengelib/tlsbench", + # Whether a YoctoWatt wattmeter is used (measuring target, USB plugged to controller) + "wattmeter": False, + # Whether perf is used to monitor target + # If using perf, reduce experiment time to a few seconds and 1 repeat, and ensure good storage bandwidth and large RAM. + "perf": False, + # Whether RAPL is used to estimate target power consumption + "rapl": False, + # Whether sa is used to count CPU time on the target + "sa": False, + # Server listen port (avoid <1024 because it may require permissions) + "listen_port": 8080, + # Log line obtained by running with --idle option. + # Will be added to every log file without re-running the idle experiment. + "idle": "target_name idle - - - - - - - - - 1779276600 1779277200 600 0 222346 1105446 2.935994312264558 0 -", + # This script will listen to this address to monitor the number of repetitions of the experiment. + # The netreplay client will send UDP packets to this port. + "notify_listen": ("0.0.0.0", 8090), + # The notify address from LAN + "notify_addr": "172.16.101.x:8090", + # LD_PRELOAD for netreplay, to override shared libraries like OpenSSL + # Must contain absolute paths to shared objects, separated by colons. + # Key is the implementation identifier. + "ld_preload": { + "openssl": "/home/pengelib/openssl-openssl-3.6.1/libssl.so.3:/home/pengelib/openssl-openssl-3.6.1/libcrypto.so.3", + }, + # Whether to create a log line for both target and controller + # Because this script's overhead may be negligible, and it enables to get twice more data. + "measure_both": False, + # Target name for the log file + "target": "my_target_computer", + # Controller target name for the log file (only used with measure_both, can be removed else) + "controller_target": "my_controller_computer", + }, "debug": { "experiments": [ "impl-cipher-ver", @@ -34,42 +111,9 @@ CONFIGS = { "listen_port": 8080, "notify_listen": ("127.0.0.1", 8090), "notify_addr": "127.0.0.1:8090", + "measure_both": False, + "target": "debug", }, - # i7-4790 local - "local": { - "experiments": [ - "impl-cipher-ver", - "impl-cert-ver", - "impl-kex-ver", - "zrtt", - ], - "sides": [ - "client", - "server", - ], - "tls": [ - #False, - True, - ], - "records": [ - { "filename": "wikipedia", "repeat": 5 }, - ], - "repo_dir": "/home/tuxmain/reps/tlsbench", - "exp_dir": "/dev/shm/exp", - "log_backup_dir": "/home/tuxmain", - "local_addr": "127.0.0.1", - "remote_addr": "127.0.0.1", - "remote_repo_dir": "/home/tuxmain/reps/tlsbench", - "wattmeter": False, - "perf": True, - "rapl": False, - "sa": True, - "perf_dir": "/home/tuxmain/.cache/exp", - "listen_port": 8080, - "notify_listen": ("127.0.0.1", 8090), - "notify_addr": "127.0.0.1:8090", - }, - # i7-4790 -> pi3 "pi3": { "experiments": [ #"impl-cipher-ver", @@ -105,12 +149,13 @@ CONFIGS = { "rapl": False, "sa": True, "listen_port": 8080, - "idle": "idle - - - - - - - - - - - 600.000081539154 0.0 896 4792 0.5399999999999991 0 -", + "idle": "pi3 idle - - - - - - - - - - - 600.000081539154 0.0 896 4792 0.5399999999999991 0 -", "notify_listen": ("0.0.0.0", 8090), "notify_addr": "192.168.3.1:8090", - "concurrency": "1", + "concurrency": "2", + "measure_both": False, + "target": "pi3", }, - # i7-4790 -> core2 "core2": { "experiments": [ #"impl-cipher-ver", @@ -148,42 +193,13 @@ CONFIGS = { "rapl": False, "sa": True, "listen_port": 8080, - "idle": "idle - - - - - - - - - 1777360401.7482355 1777361601.7482355 1200.0000903606415 0 589 4764 3.478999999999999 0 -", + "idle": "core2 idle - - - - - - - - - 1777360401.7482355 1777361601.7482355 1200.0000903606415 0 589 4764 3.478999999999999 0 -", "notify_listen": ("0.0.0.0", 8090), "notify_addr": "192.168.3.1:8090", "concurrency": "1", + "measure_both": False, + "target": "core2", }, - "core2-local": { - "experiments": [ - "impl-cipher-ver", - "impl-cert-ver", - "impl-kex-ver", - ], - "sides": [ - "client", - "server", - ], - "tls": [ - False, - True, - ], - "records": [ - { "filename": "wikipedia", "repeat": 10 }, - ], - "repo_dir": "/home/exp/exp", - "exp_dir": "/dev/shm/exp", - "log_backup_dir": "/home/exp", - "local_addr": "127.0.0.1", - "remote_addr": "127.0.0.1", - "remote_repo_dir": "/home/exp/exp", - "wattmeter": False, - "perf": True, - "rapl": False, - "sa": True, - "perf_dir": "/home/exp/.cache/exp", - "listen_port": 8080, - }, - # i7-4790 -> i5-7300HQ "i5": { "experiments": [ #"impl-cipher-ver", @@ -219,43 +235,15 @@ CONFIGS = { "rapl": True, "sa": True, "listen_port": 8080, - "idle": "idle - - - - - - - - - 1772446308.8950071 1772447508.8950853 1200.000078201294 0 1747 6555 2.4309999999999974 564883014 -", + "idle": "i5 idle - - - - - - - - - 1772446308.8950071 1772447508.8950853 1200.000078201294 0 1747 6555 2.4309999999999974 564883014 -", "notify_listen": ("0.0.0.0", 8090), "notify_addr": "192.168.3.1:8090", "ld_preload": { "openssl": "/home/tuxmain/reps/tlsbench/libssl.so:/home/tuxmain/reps/tlsbench/libcrypto.so", }, - "concurrency": "1", - }, - "i5-local": { - "experiments": [ - "impl-cipher-ver", - "impl-cert-ver", - "impl-kex-ver", - ], - "sides": [ - "client", - "server", - ], - "tls": [ - False, - True, - ], - "records": [ - { "filename": "wikipedia", "repeat": 100 }, - ], - "repo_dir": "/home/exp/exp", - "exp_dir": "/dev/shm/exp", - "log_backup_dir": "/home/exp", - "local_addr": "127.0.0.1", - "remote_addr": "127.0.0.1", - "remote_repo_dir": "/home/exp/exp", - "wattmeter": False, - "perf": True, - "rapl": False, - "sa": True, - "perf_dir": "/home/exp/.cache/exp", - "listen_port": 8080, + "concurrency": "2", + "measure_both": False, + "target": "i5", }, "g5k": { "experiments": [ @@ -294,12 +282,15 @@ CONFIGS = { "rapl": False, "sa": False, "listen_port": 8080, - "idle": "idle - - - - - - - - - 1779276600 1779277200 600 0 222346 1105446 2.935994312264558 0 -", + "idle": "paradoxe-todo idle - - - - - - - - - 1779276600 1779277200 600 0 222346 1105446 2.935994312264558 0 -", "notify_listen": ("0.0.0.0", 8090), "notify_addr": "172.16.101.x:8090", "ld_preload": { "openssl": "/home/pengelib/openssl-openssl-3.6.1/libssl.so.3:/home/pengelib/openssl-openssl-3.6.1/libcrypto.so.3", - } + }, + "measure_both": True, + "target": "paradoxe-x", + "controller_target": "paradoxe-x", }, } @@ -756,6 +747,8 @@ def run_exp(config, only_record=None, idle=False, shutdown=False, debug=False): log_backup_dir = config["log_backup_dir"] remote_path = config["remote_repo_dir"] config_name = config["name"] + target = config["target"] + controller_target = config.get("controller_target") wattmeter = None if config["wattmeter"]: errmsg = YRefParam() @@ -780,7 +773,7 @@ def run_exp(config, only_record=None, idle=False, shutdown=False, debug=False): logfile_name = "log-"+timestr logfile_path = exp_dir+"/"+logfile_name logfile = open(logfile_path, "w") - logfile.write("exp impl alg kex cipher ed side tls record n start stop time cpu bytes_in bytes_out Wh Wh_rapl prof\n") + logfile.write("target exp impl alg kex cipher ed side tls record n start stop time cpu bytes_in bytes_out Wh Wh_rapl prof\n") logfile.close() perf_dir = "" @@ -817,7 +810,7 @@ def run_exp(config, only_record=None, idle=False, shutdown=False, debug=False): while True: try: with open(logfile_path, "a") as logfile: - logfile.write(f"idle - - - - - - - - - {start} {end} {time_diff} 0 {remote_bytes_in_diff} {remote_bytes_out_diff} {energy_diff} {energy_rapl_diff} -\n") + logfile.write(f"{target} idle - - - - - - - - - {start} {end} {time_diff} 0 {remote_bytes_in_diff} {remote_bytes_out_diff} {energy_diff} {energy_rapl_diff} -\n") logfile.close() break except Exception as e: @@ -951,8 +944,11 @@ def run_exp(config, only_record=None, idle=False, shutdown=False, debug=False): # Measure cpu = 0 + controller_cpu = 0 if config["sa"]: cpu = get_cpu_stat(ssh, ["netreplay-"+impl, "tokio-runtime-w", "tokio-rt-worker"]) + if config["measure_both"]: + controller_cpu = get_cpu_stat(None, ["netreplay-"+impl, "tokio-runtime-w", "tokio-rt-worker"]) remote_bytes_in, remote_bytes_out = get_net_stat(ssh) energy = 0 energy_rapl = 0 @@ -1004,11 +1000,15 @@ def run_exp(config, only_record=None, idle=False, shutdown=False, debug=False): # Measure CPU after (as it may update only after the process is killed) new_cpu = 0 + new_controller_cpu = 0 if config["sa"]: new_cpu = get_cpu_stat(ssh, ["netreplay-"+impl, "tokio-runtime-w", "tokio-rt-worker"]) + if config["measure_both"]: + new_controller_cpu = get_cpu_stat(None, ["netreplay-"+impl, "tokio-runtime-w", "tokio-rt-worker"]) record_filename = record["filename"] cpu_diff = new_cpu - cpu + controller_cpu_diff = controller_new_cpu - controller_cpu remote_bytes_in_diff = new_remote_bytes_in - remote_bytes_in remote_bytes_out_diff = new_remote_bytes_out - remote_bytes_out energy_diff = new_energy - energy @@ -1017,7 +1017,10 @@ def run_exp(config, only_record=None, idle=False, shutdown=False, debug=False): while True: try: with open(logfile_path, "a") as logfile: - logfile.write(f"{expname} {impl} {alg} {kex} {cipher} {earlydata} {side} {tls_int} {record_filename} {session_count} {start} {end} {time_diff} {cpu_diff} {remote_bytes_in_diff} {remote_bytes_out_diff} {energy_diff} {energy_rapl_diff} {prof_filename}\n") + logfile.write(f"{target} {expname} {impl} {alg} {kex} {cipher} {earlydata} {side} {tls_int} {record_filename} {session_count} {start} {end} {time_diff} {cpu_diff} {remote_bytes_in_diff} {remote_bytes_out_diff} {energy_diff} {energy_rapl_diff} {prof_filename}\n") + if config["measure_both"]: + other_side = "client" if side == "server" else "server" + logfile.write(f"{controller_target} {expname} {impl} {alg} {kex} {cipher} {earlydata} {other_side} {tls_int} {record_filename} {session_count} {start} {end} {time_diff} {controller_cpu_diff} {remote_bytes_out_diff} {remote_bytes_in_diff} 0 0 -\n") logfile.close() break except Exception as e: diff --git a/g5kwatt.py b/g5kwatt.py index 2b0c910..c94ac85 100644 --- a/g5kwatt.py +++ b/g5kwatt.py @@ -36,7 +36,7 @@ def fetch(site, node, start, stop, user, psw): "w_avg": ws / (stop - start) } -def insert_wh_into_logfile(path, site, node, user, psw): +def insert_wh_into_logfile(path, site, user, psw): # Read logfile = open(path, "r") lines = logfile.readlines() @@ -44,9 +44,6 @@ def insert_wh_into_logfile(path, site, node, user, psw): # Parse colnames = lines[0].removesuffix("\n").split(" ") - col_start = colnames.index("start") - col_start = colnames.index("stop") - col_start = colnames.index("Wh") logs = [] records = {} @@ -72,7 +69,7 @@ def insert_wh_into_logfile(path, site, node, user, psw): # Modify if col == "Wh" and (log[col] == "-" or log[col] == "0") and not abort: try: - measure = fetch(site, node, float(log["start"]), float(log["stop"]), user, psw) + measure = fetch(site, log["target"], float(log["start"]), float(log["stop"]), user, psw) log[col] = str(measure["Wh"]) except Exception as e: print("Abort:", e) @@ -102,16 +99,15 @@ def get_psw(): def main(): if len(sys.argv) < 5: print("Usage:") - print("python g5watt.py ") + print("python g5watt.py ") exit(0) user = sys.argv[1] site = sys.argv[2] - node = sys.argv[3] - path = sys.argv[4] + path = sys.argv[3] psw = get_psw() - insert_wh_into_logfile(path, site, node, user, psw) + insert_wh_into_logfile(path, site, user, psw) if __name__ == "__main__": main() diff --git a/plots.py b/plots.py index 6c005a0..87ad4c9 100644 --- a/plots.py +++ b/plots.py @@ -67,13 +67,13 @@ CRITERION_TITLE = { "ed": "0-RTT", } PRETTY_TABLE = { - "pi3": "$\\pi$3", + "pi3": "Pi", "wp2": "WP", "yt2-ads": "YT", "yt2-ublock": "YT+µ", } PRETTY_TABLE_GNUPLOT = { - "pi3": "$\\\\pi$3", + "pi3": "Pi", "wp2": "WP", "yt2-ads": "YT", "yt2-ublock": "YT+µ", @@ -1180,15 +1180,15 @@ def make_summary_plot(logs_by_target): print(tabulate(lines)) print() - print("\ - \\multicolumn{1}{|c|}{\\textbf{Target}}&\ - \\multicolumn{1}{|c|}{\\textbf{Idle}}&\ - \\multicolumn{1}{|c|}{\\textbf{Record}}&\ - \\multicolumn{1}{|c|}{\\textbf{Side}}&\ - \\multicolumn{1}{|c|}{\\textbf{Energy}}&\ + \\multicolumn{1}{|c|}{\\multirow{2}*{\\textbf{Target}}}&\ + \\multicolumn{1}{|c|}{\\multirow{2}*{\\textbf{Idle (W)}}}&\ + \\multicolumn{1}{|c|}{\\multirow{2}*{\\textbf{Record}}}&\ + \\multicolumn{1}{|c|}{\\multirow{2}*{\\textbf{Side}}}&\ + \\multicolumn{1}{|c|}{\\multirow{2}*{\\textbf{Energy (J)}}}&\ \\multicolumn{2}{|c|}{\\textbf{Traffic}}\ \\\\") + print("\\cline{6-7}&&&&&\\multicolumn{1}{|c|}{(MB)}&\\multicolumn{1}{|c|}{(J)}\\\\") latex_lines = {} latex_keys = [] for log in results: @@ -1198,13 +1198,13 @@ def make_summary_plot(logs_by_target): latex_keys.append(key) latex_lines[key] = [ PRETTY_TABLE.get(log["target"], log["target"]), - "${}$W".format(roundz(log["idle_energy"], 2)), + "${}$".format(roundz(log["idle_energy"], 2)), PRETTY_TABLE[log["record"]], log["side"], - "${}$J".format(roundz(log["plain_energy"], 2)), - "${}$MB".format(roundz(log["plain_io"]/1024**2, 1)), - #"${}$J".format(roundz(log["plain_io"] * WS_PER_BYTE, 2)) - "${}$J".format(int(log["plain_io"] * WS_PER_BYTE)) + "${}$".format(roundz(log["plain_energy"], 2)), + "${}$".format(roundz(log["plain_io"]/1024**2, 1)), + #"${}$".format(roundz(log["plain_io"] * WS_PER_BYTE, 2)) + "${}$".format(int(log["plain_io"] * WS_PER_BYTE)) ] latex_keys.sort() last = None @@ -1237,7 +1237,7 @@ def make_summary_plot(logs_by_target): if last[3] == latex_lines[key][3]: cline = 5 - print(f"\cline{{{cline}-7}} " + " & ".join(line) + "\\\\") + print(f"\\cline{{{cline}-7}} " + " & ".join(line) + "\\\\") last = latex_lines[key] key_i += 1