1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
|
#!/bin/bash
#
# This script assumes that 2 machines are used to generate performance results.
# First machine is assumed to be the one where this script runs.
# Second machine is the "REMOTE_IP_SSH" machine; we assume to have passwordless SSH access.
#
# Usage example:
# export REMOTE_IP_SSH=10.0.0.1
# export LOCAL_TEST_ENDPOINT="tcp://192.168.1.1:1234"
# export REMOTE_TEST_ENDPOINT="tcp://192.168.1.2:1234"
# export REMOTE_LIBZMQ_PATH="/home/fmontorsi/libzmq/perf"
# ./generate_csv.sh
#
set -u
# configurable values (via environment variables):
REMOTE_IP_SSH=${REMOTE_IP_SSH:-127.0.0.1}
REMOTE_LIBZMQ_PATH=${REMOTE_LIBZMQ_PATH:-/root/libzmq/perf}
LOCAL_TEST_ENDPOINT=${LOCAL_TEST_ENDPOINT:-tcp://192.168.1.1:1234}
REMOTE_TEST_ENDPOINT=${REMOTE_TEST_ENDPOINT:-tcp://192.168.1.2:1234}
# constant values:
MESSAGE_SIZE_LIST="8 16 32 64 128 256 512 1024 2048 4096 8192 16384 32768 65536 131072"
OUTPUT_DIR="results"
OUTPUT_FILE_PREFIX="results.txt"
OUTPUT_FILE_CSV_PREFIX="results.csv"
# utility functions:
function verify_ssh()
{
ssh $REMOTE_IP_SSH "ls /" >/dev/null
if [ $? -ne 0 ]; then
echo "Cannot connect via SSH passwordless to the REMOTE_IP_SSH $REMOTE_IP_SSH. Please fix the problem and retry."
exit 2
fi
ssh $REMOTE_IP_SSH "ls $REMOTE_LIBZMQ_PATH" >/dev/null
if [ $? -ne 0 ]; then
echo "The folder $REMOTE_LIBZMQ_PATH is not valid. Please fix the problem and retry."
exit 2
fi
echo "SSH connection to the remote $REMOTE_IP_SSH is working fine."
}
function run_remote_perf_util()
{
local MESSAGE_SIZE_BYTES="$1"
local REMOTE_PERF_UTIL="$2"
local NUM_MESSAGES="$3"
echo "Launching on $REMOTE_IP_SSH the utility [$REMOTE_PERF_UTIL] for messages ${MESSAGE_SIZE_BYTES}B long"
ssh $REMOTE_IP_SSH "$REMOTE_LIBZMQ_PATH/$REMOTE_PERF_UTIL $TEST_ENDPOINT $MESSAGE_SIZE_BYTES $NUM_MESSAGES" &
if [ $? -ne 0 ]; then
echo "Failed to launch remote perf util."
exit 2
fi
}
function generate_output_file()
{
local LOCAL_PERF_UTIL="$1" # must be the utility generating the TXT output
local REMOTE_PERF_UTIL="$2"
local OUTPUT_FILE_PREFIX="$3"
local NUM_MESSAGES="$4"
local CSV_HEADER_LINE="$5"
# derived values:
local OUTPUT_FILE_TXT="${OUTPUT_DIR}/${OUTPUT_FILE_PREFIX}.txt" # useful just for human-friendly debugging
local OUTPUT_FILE_CSV="${OUTPUT_DIR}/${OUTPUT_FILE_PREFIX}.csv" # actually used to later produce graphs
local MESSAGE_SIZE_ARRAY=($MESSAGE_SIZE_LIST)
echo "Killing still-running ZMQ performance utils, if any"
pkill $LOCAL_PERF_UTIL # in case it's running from a previous test
if [ ! -z "$REMOTE_PERF_UTIL" ]; then
ssh $REMOTE_IP_SSH "pkill $REMOTE_PERF_UTIL" # in case it's running from a previous test
fi
echo "Resetting output file $OUTPUT_FILE_TXT and $OUTPUT_FILE_CSV"
mkdir -p ${OUTPUT_DIR}
> $OUTPUT_FILE_TXT
echo "$CSV_HEADER_LINE" > $OUTPUT_FILE_CSV
for MESSAGE_SIZE in ${MESSAGE_SIZE_ARRAY[@]}; do
echo "Launching locally the utility [$LOCAL_PERF_UTIL] for messages ${MESSAGE_SIZE}B long"
./$LOCAL_PERF_UTIL $TEST_ENDPOINT $MESSAGE_SIZE $NUM_MESSAGES >${OUTPUT_FILE_TXT}-${MESSAGE_SIZE} &
if [ ! -z "$REMOTE_PERF_UTIL" ]; then
run_remote_perf_util $MESSAGE_SIZE $REMOTE_PERF_UTIL $NUM_MESSAGES
fi
wait
# produce the complete human-readable output file:
cat ${OUTPUT_FILE_TXT}-${MESSAGE_SIZE} >>${OUTPUT_FILE_TXT}
# produce a machine-friendly file for later plotting:
local DATALINE="$(cat ${OUTPUT_FILE_TXT}-${MESSAGE_SIZE} | grep -o '[0-9.]*' | tr '\n' ',')"
echo ${DATALINE::-1} >>$OUTPUT_FILE_CSV
rm -f ${OUTPUT_FILE_TXT}-${MESSAGE_SIZE}
done
echo "All measurements completed and saved into $OUTPUT_FILE_TXT and $OUTPUT_FILE_CSV"
}
# main:
verify_ssh
THROUGHPUT_CSV_HEADER_LINE="# message_size,message_count,PPS[msg/s],throughput[Mb/s]"
# PUSH/PULL TCP throughput CSV file:
TEST_ENDPOINT="$LOCAL_TEST_ENDPOINT"
generate_output_file "local_thr" "remote_thr" \
"pushpull_tcp_thr_results" \
"1000000" \
"$THROUGHPUT_CSV_HEADER_LINE"
# PUSH/PULL INPROC throughput CSV file:
# NOTE: in this case there is no remote utility to run and no ENDPOINT to provide:
TEST_ENDPOINT="" # inproc does not require any endpoint
generate_output_file "inproc_thr" "" \
"pushpull_inproc_thr_results" \
"10000000" \
"$THROUGHPUT_CSV_HEADER_LINE"
# PUB/SUB proxy INPROC throughput CSV file:
# NOTE: in this case there is no remote utility to run and no ENDPOINT to provide:
TEST_ENDPOINT="" # inproc does not require any endpoint
generate_output_file "proxy_thr" "" \
"pubsubproxy_inproc_thr_results" \
"10000000" \
"$THROUGHPUT_CSV_HEADER_LINE"
# REQ/REP TCP latency CSV file:
# NOTE: in this case it's the remote_lat utility that prints out the data, so we swap the local/remote arguments to the bash func:
TEST_ENDPOINT="$REMOTE_TEST_ENDPOINT"
generate_output_file "remote_lat" "local_lat" \
"reqrep_tcp_lat_results" \
"10000" \
"# message_size,message_count,latency[us]"
|