Skip to content

Instantly share code, notes, and snippets.

@soyo42
Last active August 29, 2015 13:57
Show Gist options
  • Save soyo42/9837240 to your computer and use it in GitHub Desktop.
Save soyo42/9837240 to your computer and use it in GitHub Desktop.
cbench running and visualizing results
controller='10.0.42.5'
#controller='172.16.4.158'
port='6633'
loops=20
msPerTest='10000'
#msPerTest='3000'
macPerSwitch=1000
startupDelay=100
warmup=1
#switch amount array
#swSet=( 1 2 3 4 5 6 7 8 10 15 20 30 )
swSet=( 16 )
#swSet=( 10 15 20 30 )
#!/usr/bin/python
import sys
import re
import os
if len(sys.argv) < 2:
sys.stderr.write('usage:: {0} <description> <cbench logFile>\n'.format(sys.argv[0]))
sys.exit(1)
#08:40:49.368 16 switches: flows/sec: 794 735 861 819 710 979 728 791 797 820 685 729 841 607 794 759 total = 1.244898 per ms
resultRe = re.compile('^.+ f[^/]+/sec: ([0-9 ]+) total .+$')
#RESULT: 16 switches 9 tests min/max/avg/stdev = 2134.45/7520.27/5566.06/2170.36 responses/s
averageRe = re.compile('^RESULT:.+/([0-9.]+)/([0-9.]+) responses/s$')
descRe = re.compile('^#(.+)$')
def processLogFile(inputFile, idx, virginPlot):
dataFile = inputFile + '.data'
desc = None
data = open(dataFile, 'w')
average = None
sigma = None
with open(inputFile, 'r') as cbenchLog:
x = 0
y = 0
for line in cbenchLog:
mach = resultRe.search(line)
if mach:
for val in re.split(' +', mach.group(1).strip()):
data.write('{0} {1} {2}\n'.format(x, y, val))
x += 1
x = 0
y += 1
continue
if desc == None:
mach = descRe.match(line)
if mach:
desc = os.path.basename(inputFile) + ':' + mach.group(1)
continue
if average == None:
mach = averageRe.match(line)
if mach:
average = mach.group(1)
sigma = mach.group(2)
continue
data.close()
if desc == None:
desc = inputFile
plotCmd = 'replot'
if virginPlot:
plotCmd = 'splot'
print '''
name{2}="{0}";
{3} name{2} using 1:2:3 title "{1} avg[{4}+-{5}]" with lines;
'''.format(dataFile, desc, idx, plotCmd, average, sigma)
print '''
set grid;
set lmargin 10;
set rmargin 2.5;
set dgrid3d; # 50,50;
set hidden3d;
set xlabel "switch";
set ylabel "loop";
set zlabel "messages per second";
set title "cbench results: {0}";
'''.format(sys.argv[1])
idx = 0
virginPlot = True
for i in sys.argv[2:]:
sys.stderr.write(i + '\n')
processLogFile(i, idx, virginPlot)
virginPlot = False
idx += 1
print '''
set autoscale;
set terminal push;
set terminal pdf size 22cm,16cm;
set output "{0}/out3d.pdf";
replot;
set terminal pop;
set output;
replot;
pause -1;
'''.format(sys.argv[1])
#!/usr/bin/python
import sys
import re
if len(sys.argv) < 2:
sys.stderr.write('usage:: {0} <cbench logFile>\n'.format(sys.argv[0]))
sys.exit(1)
#RESULT: 1 switches 3 tests min/max/avg/stdev = 16.00/16.50/16.17/0.24 responses/s
resultRe = re.compile('^RESULT: ([0-9]+) switches [^=]+= ([0-9.]+)/([0-9.]+)/([0-9.]+)/([0-9.]+) resp.+$')
descRe = re.compile('^#(.+)$')
def processLogFile(inputFile, idx):
dataFile = inputFile + '.data'
desc = None
data = open(dataFile, 'w')
with open(inputFile, 'r') as cbenchLog:
for line in cbenchLog:
mach = resultRe.search(line)
if mach:
data.write('{0} {1} {2}\n'.format(mach.group(1), mach.group(4), mach.group(5)))
continue
if desc == None:
mach = descRe.match(line)
if mach:
desc = mach.group(1)
continue
data.close()
if desc == None:
desc = inputFile
print '''
name{2}="{0}";
replot name{2} using 1:2:3 notitle with errorbars lc rgb "red";
replot name{2} using 1:2 title "{1}" with lines;
'''.format(dataFile, desc, idx)
print '''
set grid;
set lmargin 10;
set rmargin 2.5;
set xlabel "# of switches";
set ylabel "total messages per second";
set title "cbench results";
set xrange[-0.5:0.5];
set yrange[-0.5:0.5];
plot "<echo '0 0'" notitle with points;
'''
idx = 0
for i in sys.argv[1:]:
sys.stderr.write(i + '\n')
processLogFile(i, idx)
idx += 1
print '''
set autoscale;
replot;
pause -1;
'''
# create symbolic link to oflops folder so, that cbench executable could be
# reached like this oflops/cbench/cbench (DEPRECATED)
ln -s <path to oflops folder> oflops
# cbench is not referred to by relative path, it is expected to be on path
# install cbench or place symbolic link into PATH (e.g.: ~/bin)
# 2D (suitable for visualizing summary results of multiple runs - e.g. with different amount of switches)
./runCbench.sh "description" logFolder
./processFolder.sh logFolder
gnuplot logFolder/out.plot
# 3D (suitable for visualizing per loop and switch results of one run)
./runCbench.sh "description" logFolder
./processFolder3d.sh logFolder
gnuplot logFolder/out3d.plot
#!/bin/bash
if [ -z "$1" ]; then
echo "usage:: $0 <cbl-folder>"
exit 1
fi
for i in $@; do
./generateGp.py "$i"/*.log > "$i"/out.plot
done
#!/bin/bash
if [ -z "$1" ]; then
echo "usage:: $0 <cbl-folder>"
exit 1
fi
for i in $@; do
# for data in "${i}"/*.log; do
# ./generate3dGp.py "${data}" > "${data}.plot"
# done
./generate3dGp.py "${i}" "${i}/"*.log > "${i}/out3d.plot"
done
#!/bin/bash
# ./cbench --help
# help message
# USAGE: cbench [option] # by Rob Sherwood 2010
# -c/--controller <str> hostname of controller to connect to ("localhost")
# -d/--debug enable debugging (off)
# -h/--help print this message
# -l/--loops <int> loops per test (16)
# -M/--mac-addresses <int> unique source MAC addresses per switch (100000)
# -m/--ms-per-test <int> test length in ms (1000)
# -p/--port <int> controller port (6633)
# -r/--ranged-test test range of 1..$n switches (off)
# -s/--switches <int> fake $n switches (16)
# -t/--throughput test throughput instead of latency
# -w/--warmup <int> loops to be disregarded on test start (warmup) (1)
# -C/--cooldown <int> loops to be disregarded at test end (cooldown) (0)
# -D/--delay <int> delay starting testing after features_reply is received (in ms) (0)
# -i/--connect-delay <int> delay between groups of switches connecting to the controller (in ms) (0)
# -I/--connect-group-size <int> number of switches in a connection delay group (1)
# -L/--learn-dst-macs send gratuitious ARP replies to learn destination macs before testing (on)
# -o/--dpid-offset <int> switch DPID offset (1)
if [ -z "$1" ]; then
echo "usage:: $0 <description> [log folder]"
exit 1
fi
#cbRoot="$(dirname "$(readlink -f "$0")")"
cbRoot="$(pwd)"
echo "cbRoot: ${cbRoot}"
. .runCbench.config
echo "controller: ${controller}"
echo "port: ${port}"
echo "loops: ${loops}"
echo "msPerTest: ${msPerTest}"
echo "macPerSwitch: ${macPerSwitch}"
echo "startupDelay: ${startupDelay}"
echo "warmup: ${warmup}"
echo "switches: ${swSet[@]}"
desc="$1"
shift
logDir="$1"
shift
useLog=true
if [[ "$1" == "-" ]]; then
useLog=false
shift
fi
countDownPid=
function killCount() {
#echo "killing: ${countDownPid}"
if [ -n "${countDownPid}" ]; then
kill ${countDownPid} 2&>/dev/null
fi
if [ -z $1 ]; then
exit 1
fi
}
function countDown() {
(for (( i=$1; i>=0; i-- )); do
if (( $i%5 == 0 )); then
echo -n $i
else
echo -n '.'
fi
sleep 1
done
echo)&
countDownPid=$!
}
trap killCount SIGINT SIGTERM EXIT
if ${useLog}; then
# go to log directory
if [ -n "${logDir}" ]; then
if [ ! -d "${logDir}" ]; then
mkdir --parent "${logDir}"
fi
cd "${logDir}"
fi
tStamp="$(date +'%Y%m%d-%H:%M:%S')"
lastLog=$(ls cb-????.log | sort | tail -n 1)
#echo "[${lastLog}]"
logIdRe='cb-0*([0-9]+)\.log'
if [[ ${lastLog} =~ ${logIdRe} ]]; then
lastLogId=${BASH_REMATCH[1]}
(( logId = lastLogId + 1 ))
echo "last log ID found (${lastLogId})"
else
logId=1
fi
cbenchLog="cb-$(printf '%04d' ${logId}).log"
echo -e "using logFile: ${logDir}/\e[32m${cbenchLog}\e[0m"
fi
echo -n -e "press \e[33;1mCTRL+C\e[0m to break "
countDown 5
read -t 5
killCount -
if ${useLog}; then
:> ${cbenchLog}
echo "${tStamp}" >> ${cbenchLog}
echo "#${desc}" >> ${cbenchLog}
fi
for switches in ${swSet[@]}; do
(( eta = $loops * $msPerTest / 1000 ))
echo "eta: ${eta}s"
countDown ${eta}
cbCmd="cbench -c ${controller} -p ${port} -l ${loops} -m ${msPerTest} -s ${switches} -D ${startupDelay} -w ${warmup} -M ${macPerSwitch} $@"
if ${useLog}; then
${cbCmd} 2>&1 | tee -a ${cbenchLog} | grep 'RESULT'
echo '---' >> ${cbenchLog}
else
${cbCmd}
echo '---'
fi
killCount -
sleep 2
done
date
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment