...
 
Commits (2)
__pycache__/
.ipynb_checkpoints/
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from .util import experiment_config, cdf, protos, all_colors, colors, all_markers, markers, anonymize, scatter_dot_size, scatter_dot_linewidths, linestyles, opt_linewidth
pace_columns = [
"AppSendPaceInternal",
"AppSendPaceDependent",
"AppSendPaceExternal",
"TransTransmitPaceInternal",
"TransTransmitPaceDependent",
"TransTransmitPaceExternal",
"NWPace",
"RecvBtlPace"
]
def prep(filename):
df = pd.read_csv(filename,header=None,index_col=0,names=["SendT","IPT", "AppSendPaceInternal","AppSendPaceDependent","AppSendPaceExternal","TransTransmitPaceInternal","TransTransmitPaceDependent","TransTransmitPaceExternal","RecvBtlPace","NWPace"])
df["Round"] = df.index
df["SendT"] /= 1000**2 # ns -> ms
df["IPT"] /= 1000**2 # ns -> ms
for column in pace_columns:
df[column] /= 1000 # us -> ms
return df
def ipts_cdf(folder, r=None, protocols=None, figsize = (16,5), file_name="ipt_cdf.pdf", export=False, anonymous=False, legend=None, iptopt=None):
if legend is None:
legend = {}
if r is None:
r = slice(0,-1)
p = protocols if protocols is not None else protos
exp = experiment_config(folder)
baseline = (max(exp["network_pace"], exp["app_send_delay"], exp["app_recv_delay"])) * 1000
if iptopt is not None:
baseline = iptopt
fig = plt.figure(figsize=figsize)
dfs = {}
for i, proto in enumerate(p):
df = prep("{0}/sender_{1}.csv".format(folder, proto))[r]
dfs[proto] = df
cdf(df["IPT"], grid=False, label=anonymize(proto, anonymous).upper(), color=colors[proto], linestyle=linestyles[proto])
plt.axvline(x=baseline, color=colors["line"], linewidth=opt_linewidth, linestyle=linestyles["opt"], label="$IPT_{opt}$")
if legend is not False:
plt.legend(**legend)
plt.xlabel("Inter Packet Time [ms]")
plt.ylabel("CDF")
plt.yticks(np.arange(0.0, 1.1, 0.5))
if export and file_name is not None:
fig.savefig(file_name)
return dfs
def _ipt_by_time(df,ax,proto,i,anonymous=False,legend=None):
if legend is None:
legend = {}
ax.scatter(df["SendT"], df["IPT"], label=anonymize(proto, anonymous).upper(), marker=markers[proto], color=colors[proto], s=scatter_dot_size, linewidths=scatter_dot_linewidths)
#ax.grid()
ax.semilogy()
if legend is not False:
ax.legend(**legend)
def _ipt_by_round(df,ax,proto,i,anonymous=False,legend=None):
if legend is None:
legend = {}
ax.scatter(df["Round"], df["IPT"], label=anonymize(proto, anonymous).upper(), marker=markers[proto], color=colors[proto], s=scatter_dot_size, linewidths=scatter_dot_linewidths)
#ax.grid()
ax.semilogy()
if legend is not False:
ax.legend(**legend)
def ipts_timeseries(folder, r=None, times=True, rounds=True, paces=None, protocols=None, grid=False, legend=None, figsize = (16,9), file_name="ipt.pdf", export=False, anonymous=False, iptopt=None):
if legend is None:
legend = {}
if r is None:
r = slice(0,-1)
p = protocols if protocols is not None else protos
rows = sum([times, rounds, 1 if paces is not None else 0])
fig, axes = plt.subplots(nrows=rows, ncols=1)
fig.set_size_inches(figsize[0], figsize[1])
exp = experiment_config(folder)
effective_rounds = 0
baseline = (max(exp["network_pace"], exp["app_send_delay"], exp["app_recv_delay"])) * 1000
if iptopt is not None:
baseline = iptopt
dfs = {}
for i, proto in enumerate(p):
df = prep("{}/sender_{}.csv".format(folder, proto))[r]
dfs[proto] = df
effective_rounds = len(df.index)
ax_idx = 0
if times:
_ipt_by_time(df,axes[ax_idx] if rows > 1 else axes,proto,i,anonymous,legend)
ax_idx += 1
if rounds:
_ipt_by_round(df,axes[ax_idx] if rows > 1 else axes,proto,i,anonymous,legend)
ax_idx += 1
if paces is not None and proto == "prrt":
ax = axes[ax_idx] if rows > 1 else axes
for j, name in enumerate(paces):
ax.scatter(df["Round"], df[name], label=name, marker=all_markers[j], color=all_colors[j], s=scatter_dot_size, linewidths=scatter_dot_linewidths)
ax.set_xlabel("Round Number")
ax.set_ylabel("Pace [ms]")
ax.axhline(y=baseline, color=colors["line"], linestyle=linestyles["opt"], linewidth=opt_linewidth, label="$IPT_{opt}$")
ax.semilogy()
if grid:
ax.grid()
ax.legend(loc=legend)
mintime = effective_rounds * baseline
ax_idx = 0
if times:
ax = axes[ax_idx] if rows > 1 else axes
ax.axhline(y=baseline, color=colors["line"], linestyle=linestyles["opt"], linewidth=opt_linewidth, label="$IPT_{opt}$")
ax.axvline(x=mintime, color=colors["line"], linestyle=linestyles["opt2"], linewidth=opt_linewidth, label="$EXP_{opt}$")
if legend is not False:
ax.legend(**legend)
ax.set_xlabel("Send Time [ms]")
ax.set_ylabel("Inter Packet Time [ms]")
ax_idx += 1
if rounds:
ax = axes[ax_idx] if rows > 1 else axes
ax.axhline(y=baseline, color=colors["line"], linestyle=linestyles["opt"], linewidth=opt_linewidth, label="$IPT_{opt}$")
if legend is not False:
ax.legend(**legend)
ax.set_xlabel("Round Number")
ax.set_ylabel("Inter Packet Time [ms]")
if export and file_name is not None:
fig.savefig(file_name)
return dfs
from .util import experiment_config, protos, markers, colors, cdf, anonymize, scatter_dot_size, scatter_dot_linewidths, linestyles, opt_linewidth
import pandas as pd
import numpy as np
import math
import matplotlib.pyplot as plt
pace_columns = [
"TransReceivePaceInternal",
"TransReceivePaceDependent",
"TransReceivePaceExternal",
"AppDeliverPaceInternal",
"AppDeliverPaceDependent",
"AppDeliverPaceExternal",
"SendBtlPace"]
def preprocess(filename, colname="time"):
df = pd.read_csv(filename,
header=None,
index_col=0,
names=[colname+"A",
colname,
"AppDeliverPaceInternal",
"AppDeliverPaceDependent",
"AppDeliverPaceExternal",
"TransReceivePaceInternal",
"TransReceivePaceDependent",
"TransReceivePaceExternal",
"SendBtlPace"])
df.drop([colname+"A"], axis=1, inplace=True)
df[colname].replace(to_replace=0, value=np.nan, inplace=True)
df[colname] = df[colname] / 1000.0**2 # plot ms
for column in pace_columns:
df[column] /= 1000 # us in ms
return df
def dts_box(folder, r=None):
if r is None:
r = slice(0, -1)
exp = experiment_config(folder)
baseline = (exp["delay"] + exp["network_pace"]) * 1000
df = None
for i, proto in enumerate(protos):
dfx = preprocess("{0}/receiver_{1}.csv".format(folder, proto))[r]
dfx.rename(index=str, columns={"time": proto.upper()}, inplace=True)
if df is None:
df = dfx
else:
df = df.join(dfx)
df.plot.box(grid=False, vert=False, figsize=(16, 5))
plt.axvline(x=baseline, color=colors["line"], linestyle=linestyles["opt"], label="$DT_{opt}$", linewidth=opt_linewidth)
plt.xlabel("E2E Delivery Time [ms]")
plt.legend()
def receiver_dts_cdf(folder, r=None, protocols=None,
grid=False, figsize=(16, 5),
export=False, file_name="dts_cdf.pdf",
anonymous=False,
hide_dtopt=False,
dtopt=None,
legend=None,
xlabel=True,
ylabel=True,
t_max=None):
if legend is None:
legend = {}
if r is None:
r = slice(0, -1)
p = protocols if protocols is not None else protos
exp = experiment_config(folder)
baseline = (exp["delay"] + exp["network_pace"]) * 1000
if dtopt is not None:
baseline = dtopt
fig = plt.figure(figsize=figsize)
dfs = {}
for i, proto in enumerate(p):
df = preprocess("{0}/receiver_{1}.csv".format(folder, proto))[r]
dfs[proto] = df
cdf(df["time"], grid=False, label=anonymize(proto, anonymous).upper(),
color=colors[proto], linestyle=linestyles[proto])
if xlabel:
plt.xlabel("E2E Delivery Time [ms]")
if t_max is not None:
plt.xlim([baseline*0.9,t_max*1.1])
if ylabel:
plt.ylabel("CDF")
if not hide_dtopt:
plt.axvline(x=baseline, color=colors["line"], linestyle=linestyles["opt"], linewidth=opt_linewidth, label="$DT_{opt}$")
if legend is not False:
plt.legend(**legend)
if grid:
plt.grid()
plt.yticks(np.arange(0.0, 1.1, 0.5))
if export and file_name is not None:
fig.savefig(file_name)
return dfs
def plot_dts(filename, proto, r=None,
anonymous=False,
marker="+",
color="black",
hide_tcp_cca=False,
use_icc=False,
legend=None):
if legend is None:
legend = {}
if r is None:
r = slice(0, -1)
df = preprocess(filename)[r]
plt.scatter(df.index, df["time"],
label=anonymize(proto, anonymous, hide_tcp_cca=hide_tcp_cca, use_icc=use_icc).upper(),
marker=marker, color=color, s=scatter_dot_size, linewidths=scatter_dot_linewidths)
if legend is not False:
plt.legend(**legend)
return df
def receiver_dts_timeseries(folder, r=None, protocols=None,
grid=False, figsize=(16, 9),
export=False, file_name="dts.pdf",
anonymous=False,
dtopt=None,
hide_dtopt=False,
hide_tcp_cca=False,
ylim=None,
theoretical=False,
legend=None,
ylabel=True):
if legend is None:
legend = { "loc": "upper center"}
if r is None:
r = slice(0, -1)
p = protocols if protocols is not None else protos
exp = experiment_config(folder)
baseline = (exp["delay"] + exp["network_pace"]) * 1000
if dtopt is not None:
baseline = dtopt
fig = plt.figure(figsize=figsize)
dfs = {}
for i, proto in enumerate(p):
df = plot_dts("{0}/receiver_{1}.csv".format(folder, proto), proto, r,
anonymous, marker=markers[proto], color=colors[proto], hide_tcp_cca=hide_tcp_cca, use_icc=theoretical, legend=legend)
dfs[proto] = df
plt.xlabel("Rounds")
if ylabel:
plt.ylabel("E2E Delivery Time [ms]")
if not hide_dtopt:
opt_lbl="Theoretical Minimum" if theoretical else "$DT_{opt}$"
plt.axhline(y=baseline, color=colors["line"], linestyle=linestyles["opt"], linewidth=opt_linewidth, label=opt_lbl)
if legend is not False:
plt.legend(**legend)
if ylim is not None:
plt.ylim(ylim)
if grid:
plt.grid()
plt.semilogy()
if export and file_name is not None:
fig.savefig(file_name)
return dfs
def receiver_paces(folder, r=None, grid=False):
if r is None:
r = slice(0, -1)
fig = plt.figure()
fig.set_size_inches(16, 9)
df = preprocess("{}/receiver_prrt.csv".format(folder))[r]
for j, name in enumerate(pace_columns):
plt.scatter(df.index, df[name], label=name, marker=all_markers[j],
color=colors[name], s=scatter_dot_size, linewidths=scatter_dot_linewidths)
plt.xlabel("Round Number")
plt.ylabel("Pace [ms]")
if grid:
plt.grid()
plt.legend()
return df
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import rcParams
plt.rc("figure", autolayout=True)
SMALL_SIZE = 18
MEDIUM_SIZE = 20
BIGGER_SIZE = 24
plt.rc('font', size=SMALL_SIZE) # controls default text sizes
plt.rc('axes', titlesize=SMALL_SIZE) # fontsize of the axes title
plt.rc('axes', labelsize=MEDIUM_SIZE) # fontsize of the x and y labels
plt.rc('xtick', labelsize=SMALL_SIZE) # fontsize of the tick labels
plt.rc('ytick', labelsize=SMALL_SIZE) # fontsize of the tick labels
plt.rc('legend', fontsize=MEDIUM_SIZE) # legend fontsize
plt.rc('figure', titlesize=BIGGER_SIZE) # fontsize of the figure title
protos = ["tcp-cubic", "tcp-bbr", "prrt"]
all_markers = ["*", "+", "x", "d", "o", "v", "^", "<"]
markers = {
"prrt": "*",
"tcp-cubic": "s",
"tcp-bbr": ".",
"tcp-cubic-u": "s",
"tcp-bbr-u": "d"
}
all_colors = ["green","blue","orange","purple","red","pink","yellow","black"]
colors = {
"prrt": "#E69F00",
"tcp-bbr": "#009E73",
"tcp-bbr-u": "#56B4E9",
"tcp-cubic": "#CC79A7",
"tcp-cubic-u": "#D55E00",
"line": "#000000"
}
linestyles = {
"prrt": "--",
"tcp-cubic": "-.",
"tcp-cubic-u": "-.",
"tcp-bbr": ":",
"tcp-bbr-u": ":",
"opt": "--",
"opt2": "-."
}
scatter_dot_size = 40
scatter_dot_linewidths=1
cdf_linewidth=4
opt_linewidth=4
def anonymize(proto, anonymous, hide_tcp_cca=False, use_icc=False):
if anonymous and proto == "prrt":
return "icc" if use_icc else "icp"
if hide_tcp_cca:
return proto.replace("-cubic", "").replace("-bbr", "")
return proto
def cdf(values, ax=None, grid=False, **kwargs):
if ax is None:
ax = plt
if not "linestyle" in kwargs:
kwargs["linestyle"] = "-"
s = np.sort(values)
ax.semilogx(s, np.searchsorted(s, s, side='right') / len(s), linewidth=cdf_linewidth, **kwargs)
def experiment_config(folder):
exp = pd.read_csv("{}/experiment.csv".format(folder))
size = exp.at[0,"Size"]
delay = exp.at[0,"Delay"]
jitter = exp.at[0,"Jitter"]
rate = exp.at[0,"Rate"]
bdp = exp.at[0,"BDP"]
sndbuf = exp.at[0,"SNDBUF"]
rcvbuf = exp.at[0,"RCVBUF"]
rounds = exp.at[0,"Rounds"]
return {
"delay": delay,
"jitter": jitter,
"loss": "{:.2f}%".format(exp.at[0,"Loss"] * 100),
"rate": rate,
"network_pace": (size * 8) / (rate),
"size": size,
"bdp" : bdp,
"rcvbuf" : rcvbuf,
"sndbuf" : sndbuf,
"rounds": rounds,
"app_send_delay": exp.at[0,"APP_SEND_PACE"],
"app_send_jitter": exp.at[0,"APP_SEND_JITTER"],
"app_recv_delay": exp.at[0,"APP_RECV_PACE"],
"app_recv_jitter": exp.at[0,"APP_RECV_JITTER"],
"app_send_rate": exp.at[0,"Size"] / exp.at[0,"APP_SEND_PACE"] if exp.at[0,"APP_SEND_PACE"] != 0 else np.inf,
"app_recv_rate": exp.at[0,"Size"] / exp.at[0,"APP_RECV_PACE"] if exp.at[0,"APP_RECV_PACE"] != 0 else np.inf,
#"btlbuf": exp.at[0,"BTLBUF"]
}
def duration_inflate(dfs, proto, exp, length):
last_time = dfs[proto].iloc[-1]["SendT"]
conf = experiment_config(exp)
opt = conf["app_recv_delay"] * length * 1000
return [proto, last_time/1000, opt/1000]
def experiment_duration_inflation(protos, dfs, exp, length):
rows = [duration_inflate(dfs, proto, exp, length) for proto in protos]
return pd.DataFrame(rows,columns=["Proto","EXP_ACT [ms]","EXP_OPT [ms]"]).set_index("Proto")
This diff is collapsed.