Commit aaa18272 authored by Hejing Li's avatar Hejing Li
Browse files

ae dctcp scripts

parent e2506d45
#!/bin/bash
SB_BASE="$(readlink -f $(dirname ${BASH_SOURCE[0]})/../..)"
NS3_BASE="$SB_BASE/sims/external/ns-3"
# Runs ns-3 data points in Figure 1
# It will generate simulation result files in simbricks/sims/external/ns-3
./pyexps/ae/ns3-dctcp.sh `nproc`
python3 pyexps/ae/data_ns3_dctcp.py $NS3_BASE > ae/dctcp_ns3.data
# Runs Simbricks data points in Figure 1
# It will generate simulation results in out/
python3 run.py pyexps/ae/f1_dctcp.py --filter gt-ib-* --force --verbose --parallel
# Process the results and prints
python3 pyexps/ae/data_sb_dctcp.py out/ > ae/dctcp_simbricks.data
# Copyright 2021 Max Planck Institute for Software Systems, and
# National University of Singapore
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
import itertools
import os
import sys
import utils.iperf
if len(sys.argv) != 2:
print('Usage: ns3-dctcp.py OUTDIR')
sys.exit(1)
basedir = sys.argv[1] + '/'
max_k = 199680
k_step = 16640
mtu = 4000
confignames = ["ns3-4000"]
print('\t'.join(['threshold'] + confignames))
for k_val in range(0, max_k + 1, k_step):
line = [str(k_val)]
path_pat = '%sdctcp-modes-tput-4000-%d-50us.dat' % (basedir, k_val)
tps = []
if not os.path.isfile(path_pat):
print("no result file at: " + path_pat)
exit(0)
f = open(path_pat, 'r')
lines = f.readlines()
tp = float(lines[1].split()[2]) / 1000
tps.append(tp)
tp = float(lines[2].split()[2]) / 1000
tps.append(tp)
f.close()
total_tp = sum(tps)
# TP * (MTU + PPP(2)) / (MTU - IP (20) - TCP w/option (24))
tp_calib = total_tp * (mtu + 2) / (mtu - 20 - 24)
line.append('%.2f' % (tp_calib))
print('\t'.join(line))
\ No newline at end of file
# Copyright 2021 Max Planck Institute for Software Systems, and
# National University of Singapore
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
import itertools
import sys
import utils.iperf
if len(sys.argv) != 2:
print('Usage: dctcp.py OUTDIR')
sys.exit(1)
basedir = sys.argv[1] + '/'
types_of_host = ['gt']
mtus = [4000]
max_k = 199680
k_step = 16640
configs = list(itertools.product(types_of_host, mtus))
confignames = [h + '-' + str(mtu) for h, mtu in configs]
print('\t'.join(['threshold'] + confignames))
for k_val in range(0, max_k + 1, k_step):
line = [str(k_val)]
for h, mtu in configs:
path_pat = '%s%s-ib-dumbbell-DCTCPm%d-%d' % (basedir, h, k_val, mtu)
res = utils.iperf.parse_iperf(path_pat)
if res['avg'] is None:
line.append('')
continue
tp = res['avg']
# TP * (MTU ) / (MTU - IP (20) - TCP w/option (24))
if (h == 'gt' or h == 'qt'):
tp_calib = tp * (mtu) / (mtu - 20 - 24)
else:
# TP * (MTU + ETH(14) + PHY(24)) / (MTU - IP (20) - TCP w/option (24))
tp_calib = tp * (mtu + 14 + 24) / (mtu - 20 - 24)
line.append('%.2f' % (tp_calib))
print('\t'.join(line))
# Copyright 2021 Max Planck Institute for Software Systems, and
# National University of Singapore
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
"""
This script is for reproducing Simbricks line in [Figure 1] DCTCP result.
We used following combination of simulators.
HOST: Gem5 timing CPU
NIC: Intel i40e behavioral model
NET: ns-3 dumbbell model
The simulation composed of two pairs of iperf server and client, connected
in a dumbbell topology.
The link between two switches is the bottleneck link.
[HOST_0]-[NIC_0]-----[SWITCH]---[SWITCH]-----[NIC_1]-[HOST_1]
server_0 | | client_0
| |
[HOST_0]-[NIC_0]---------- ---------- [NIC_1]-[HOST_1]
server_1 client_1
The command to run all the experiments is:
$: python3 run.py pyexps/ae/f1_dctcp.py --filter gt-ib-* --force --verbose
"""
import simbricks.experiments as exp
import simbricks.simulators as sim
import simbricks.nodeconfig as node
from simbricks.simulator_utils import create_dctcp_hosts
types_of_host = ['gt']
types_of_nic = ['ib']
types_of_net = ['dumbbell']
types_of_app = ['DCTCPm']
types_of_mtu = [4000]
num_pairs = 2
max_k = 199680
k_step = 16640
link_rate_opt = '--LinkRate=10Gb/s ' # don't forget space at the end
link_latency_opt = '--LinkLatency=500ns '
cpu_freq = '5GHz'
cpu_freq_qemu = '2GHz'
sys_clock = '1GHz' # if not set, default 1GHz
ip_start = '192.168.64.1'
experiments = []
# set network sim
net_class = sim.NS3DumbbellNet
for mtu in types_of_mtu:
for h in types_of_host:
for c in types_of_nic:
for k_val in range(0, max_k + 1, k_step):
net = net_class()
net.opt = link_rate_opt + link_latency_opt + f'--EcnTh={k_val}'
e = exp.Experiment( h + '-' + c + '-' + 'dumbbell' + '-' + 'DCTCPm' + f'{k_val}' + f'-{mtu}')
e.add_network(net)
freq = cpu_freq
# host
if h == 'qemu':
host_class = sim.QemuHost
elif h == 'qt':
freq = cpu_freq_qemu
def qemu_timing():
h = sim.QemuHost()
h.sync = True
return h
host_class = qemu_timing
elif h == 'gt':
def gem5_timing():
h = sim.Gem5Host()
#h.sys_clock = sys_clock
return h
host_class = gem5_timing
e.checkpoint = True
elif h == 'gO3':
def gem5_o3():
h = sim.Gem5Host()
h.cpu_type = 'DerivO3CPU'
h.sys_clock = sys_clock
return h
host_class = gem5_o3
e.checkpoint = True
else:
raise NameError(h)
# nic
if c == 'ib':
nic_class = sim.I40eNIC
nc_class = node.I40eDCTCPNode
elif c == 'cb':
nic_class = sim.CorundumBMNIC
nc_class = node.CorundumDCTCPNode
elif c == 'cv':
nic_class = sim.CorundumVerilatorNIC
nc_class = node.CorundumDCTCPNode
else:
raise NameError(c)
servers = create_dctcp_hosts(e, num_pairs, 'server', net, nic_class, host_class,
nc_class, node.DctcpServer, freq, mtu)
clients = create_dctcp_hosts(e, num_pairs, 'client', net, nic_class, host_class,
nc_class, node.DctcpClient, freq, mtu, ip_start=num_pairs+1)
i = 0
for cl in clients:
cl.node_config.app.server_ip = servers[i].node_config.ip
i += 1
# All the clients will not poweroff after finishing iperf test except the last one
# This is to prevent the simulation gets stuck when one of host exits.
# The last client waits for the output printed in other hosts, then cleanup
clients[num_pairs-1].node_config.app.is_last = True
clients[num_pairs-1].wait = True
print(e.name)
experiments.append(e)
# Copyright 2021 Max Planck Institute for Software Systems, and
# National University of Singapore
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
########################################################################
# This script is for reproducing [Figure 9] in the paper.
# It generates experiments for
#
# Host type has qemu-kvm(qemu in short), gem5-timing-mode(gt), qemu-timing-mode(qt)
# Nic type has Intel_i40e behavioral model(ib), corundum behavioral model(cb), corundum verilator(cv)
# Net type has Switch behavioral model(sw), ns-3(ns3)
#
# In each simulation, two hosts are connected by a switch
# [HOST_0] - [NIC_0] ---- [SWITCH] ---- [NIC_1] - [HOST_1]
# server client
#
# The server host runs netperf server and client host runs TCP_RR and
# TCP_STREAM test
#
# The command to run all the experiments is:
# $: python3 run.py pyexps/ae/t1_combination.py --filter nf-* --verbose
########################################################################
import simbricks.experiments as exp
import simbricks.simulators as sim
import simbricks.nodeconfig as node
from simbricks.simulator_utils import create_basic_hosts
pci_latency = [10, 50, 100, 500, 1000]
experiments = []
for pci_type in pci_latency:
e = exp.Experiment('pci-gt-ib-sw-' + f'{pci_type}')
net = sim.SwitchNet()
e.add_network(net)
host_class = sim.Gem5Host
e.checkpoint = True
nic_class = sim.I40eNIC
nc_class = node.I40eLinuxNode
# create servers and clients
servers = create_basic_hosts(e, 1, 'server', net, nic_class, host_class,
nc_class, node.NetperfServer)
clients = create_basic_hosts(e, 1, 'client', net, nic_class, host_class,
nc_class, node.NetperfClient, ip_start = 2)
for c in clients:
c.wait = True
c.node_config.app.server_ip = servers[0].node_config.ip
# add to experiments
experiments.append(e)
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
##### ./ns3-dctcp.sh [num_core] ##### ./ns3-dctcp.sh [num_core]
EHSIM_BASE="$(readlink -f $(dirname ${BASH_SOURCE[0]})/../..)" EHSIM_BASE="$(readlink -f $(dirname ${BASH_SOURCE[0]})/../../..)"
NS3_BASE="$EHSIM_BASE/sims/external/ns-3" NS3_BASE="$EHSIM_BASE/sims/external/ns-3"
OUTDIR_BASE="$EHSIM_BASE/experiments/pyexps" OUTDIR_BASE="$EHSIM_BASE/experiments/pyexps"
......
# Copyright 2021 Max Planck Institute for Software Systems, and
# National University of Singapore
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
import glob
import json
import os
import fnmatch
import re
import itertools
import sys
def parse_iperf_run(data, skip=1, use=8):
tp_pat = re.compile(r'\[ *\d*\] *([0-9\.]*)- *([0-9\.]*) sec.*Bytes *([0-9\.]*) ([GM])bits.*')
tps_time = {}
for hn in fnmatch.filter(data['sims'].keys(), 'host.client.*'):
sim = data['sims'][hn]
for l in sim['stdout']:
m = tp_pat.match(l)
if not m:
continue
time = int(float(m.group(1)))
if time < skip:
continue
if time >= skip + use:
continue
if not time in tps_time:
tps_time[time] = []
if m.group(4) == 'G':
tps_time[time].append(float(m.group(3)))
elif m.group(4) == 'M':
m_tps = float(m.group(3))/1000
tps_time[time].append(m_tps)
tps = []
for t in sorted(tps_time.keys()):
x = sum(tps_time[t])
tps.append(x)
if len(tps) == 0:
return None
return sum(tps) / len(tps)
def parse_iperf(basename, skip=1, use=8):
runs = []
for path in glob.glob(basename + '-*.json'):
if path == basename + '-0.json':
# skip checkpoints
continue
with open(path, 'r') as f:
data = json.load(f)
result = parse_iperf_run(data, skip, use)
if result is not None:
runs.append(result)
if not runs:
return {'avg': None, 'min': None, 'max': None}
else:
return {'avg': sum(runs) / len(runs), 'min': min(runs),
'max': max(runs)}
result = {}
# Copyright 2021 Max Planck Institute for Software Systems, and
# National University of Singapore
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
import json
import re
import os
def parse_netperf_run(path):
ret = {}
if not os.path.exists(path):
return ret
with open(path, 'r') as f:
data = json.load(f)
ret['simtime'] = data['end_time'] - data['start_time']
tph_pat = re.compile(r'Size\s*Size\s*Size\s*Time\s*Throughput.*')
start = None
i = 0
lines = data['sims']['host.client.0']['stdout']
for l in lines:
if tph_pat.match(l):
start = i
break
i += 1
if start is not None:
tp_line = lines[start + 3]
tp_pat = re.compile(r'\s*\d*\s*\d*\s*\d*\s*[0-9\.]*\s*([0-9\.]*).*')
m = tp_pat.match(tp_line)
ret['throughput'] = float(m.group(1))
lath_pat = re.compile(r'\s*Mean Latency.*')
start = None
i = 0
lines = data['sims']['host.client.0']['stdout']
for l in lines:
if lath_pat.match(l):
start = i
break
i += 1
if start is not None:
lat_line = lines[start + 1]
lat_pat = re.compile(r'\s*([-0-9\.]*),([-0-9\.]*),([-0-9\.]*),([-0-9\.]*).*')
m = lat_pat.match(lat_line)
ret['latenyMean'] = float(m.group(1))
ret['latenyTail'] = float(m.group(4))
return ret
# Copyright 2021 Max Planck Institute for Software Systems, and
# National University of Singapore
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
import json
import re
import os
def parse_nopaxos_run(num_c, seq, path):
ret = {}
ret['throughput'] = None
ret['latency'] = None
tp_pat = re.compile(r'(.*)Completed *([0-9\.]*) requests in *([0-9\.]*) seconds')
lat_pat = re.compile(r'(.*)Average latency is *([0-9\.]*) ns(.*)')
if not os.path.exists(path):
return ret
f_log = open(path, 'r')
log = json.load(f_log)
total_tput = 0
total_avglat = 0
for i in range(num_c):
sim_name = f'host.client.{i}'
#print(sim_name)
# in this host log stdout
for j in log["sims"][sim_name]["stdout"]:
#print(j)
m_t = tp_pat.match(j)
m_l = lat_pat.match(j)
if m_l:
#print(j)
lat = float(m_l.group(2)) / 1000 # us latency
#print(lat)
total_avglat += lat
if m_t:
n_req = float(m_t.group(2))
n_time = float(m_t.group(3))
total_tput += n_req/n_time
avglat = total_avglat/num_c
#print(avglat)
#print(total_tput)
ret['throughput'] = total_tput
ret['latency'] = avglat
return ret
...@@ -22,8 +22,8 @@ ...@@ -22,8 +22,8 @@
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
##### build dctcp-modes.cc example in ns-3 ##### build dctcp-cwnd-devred.cc example in ns-3
##### cp cp examples/tcp/dctcp-modes.cc scratch/dctcp-modes.cc ##### cp cp examples/tcp/dctcp-cwnd-devred.cc scratch/
##### ./waf ##### ./waf
##### ./ns3-dctcp.sh [num_core] ##### ./ns3-dctcp.sh [num_core]
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment