1.3.3. RTI Persistence Service

1.3.3.1. Unkeyed, UDPv4 10Gbps Network

The graph below shows the one-way latency without load between a Publisher and a Subscriber running in two Linux nodes in a 10Gbps network. The numbers are for best-effort as well as strict reliable reliability scenarios.

Note

We use the median (50th percentile) instead of the average in order to get a more stable measurement that does not account for spurious outliers. We also calculate the average value and other percentile values, which can be seen in the Detailed Statistics section below.

Detailed Statistics

The following tables contain the raw numbers presented by RTI Perftest. These numbers are the exact output with no further processing.

  • Reliable

How to read the latency tables and plots:

  • Avg: Mean of the avg values for N runs per sample size.
  • Std: Standard deviation of the avg values across N runs. High values suggest inconsistency across runs.
  • Plot representation: for each sample size, all N individual values are plotted as circles. The line connects the average of the N values (‘Avg’ in the table) across all sample sizes.
Note: each row represents a different sample size, and the values are aggregated across N runs for that size.

Sample Size

Avg

P-50

Std

Min

Max

P-99

P-9999

32

16.99

16.8

1.11

16.03

87.25

19.69

48.51

256

18

17.59

6.01

16.77

4944

30.97

54.41

512

20.3

19.72

3.19

17.44

116.47

37.03

62.63

1024

26.02

26.48

12.33

18.45

4748.38

45.47

74.71

8192

44.88

39.51

13.6

36.21

4703.96

79.11

123.24

63000

187.54

187.56

2.5

121.29

221.98

191.42

200.03


Perftest Scripts

To produce these tests, we executed RTI Perftest for C++98 and Persistence Service. The exact script used can be found here:

  1#!/bin/bash
  2filename=$0
  3
  4# This is in order to know where is the script and where is the repo base folder
  5script_location=$(cd "$(dirname "$filename")" || exit 255; pwd)
  6repo_location=`cd "$script_location/../.."; pwd`
  7
  8################################################################################
  9
 10# We will use some colors to improve visibility of errors and information
 11RED='\033[0;31m'
 12GREEN='\033[0;32m'
 13YELLOW='\033[0;33m'
 14NC='\033[0m'
 15INFO_TAG="${GREEN}[INFO]:${NC}"
 16WARNING_TAG="${YELLOW}[WARNING]:${NC}"
 17ERROR_TAG="${RED}[ERROR]:${NC}"
 18
 19# Use key-based SSH only and fail fast instead of prompting for a password.
 20export ssh="ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o LogLevel=ERROR -o BatchMode=yes -o PreferredAuthentications=publickey -o PasswordAuthentication=no -o KbdInteractiveAuthentication=no -o NumberOfPasswordPrompts=0 -o ConnectTimeout=8 -o ConnectionAttempts=1"
 21
 22################################################################################
 23
 24# Default Lab to use.
 25export LAB="LINUX_X64"
 26
 27# TEST RELATED CONSTANTS
 28
 29# Some default values for certain variables like openssl
 30export openssl_1_version="openssl-1.1.1s"
 31export openssl_3_version="openssl-3.0.12"
 32export openssl_309_version="openssl-3.0.9"
 33export openssl_3011_version="openssl-3.0.11"
 34export openssl_350_version="openssl-3.5.0"
 35export openssl_355_version="openssl-3.5.5"
 36export wolfssl_version="wolfssl-5.5.1"
 37export JAVA_LINUX_BIN_PATH="/local/apps/Java/PLATFORMSDK/linux64/jdk-11.0.7+10/bin"
 38export DOTNET6_LINUX_BIN_PATH="/local/apps/dotnet/dotnet-sdk-5.0.103-linux-x64"
 39
 40export middleware="pro"
 41export TEST_KIND="throughput"
 42export KEYED_UNKEYED="unkeyed"
 43export MULTICAST_UNICAST="unicast"
 44export timeout_value=200
 45export machines_to_use=""
 46
 47################################################################################
 48### FUNCTIONS
 49
 50### Cleaning funtion:
 51
 52function clean_machines () {
 53
 54    if ! validate_ssh_connectivity_all_machines; then
 55        echo -e "$ERROR_TAG Aborting cleanup due to SSH connectivity failures."
 56        return 1
 57    fi
 58
 59    echo -e "${YELLOW}Clean Machines${NC}: Launching cleanup in parallel for ${number_machines} machine(s)..."
 60
 61    for ((i = 0 ; i < number_machines ; i++)); do
 62        (
 63            $ssh "${machines[$i]}" pkill perftest_cpp >/dev/null 2>&1 || true
 64            # stdout and stderr in tcsh to /dev/null
 65            $ssh "${machines[$i]}" killall -s KILL /bin/bash >/dev/null 2>&1 || true
 66
 67            if [[ "${machines[$i]}" == "$tcpdump_machine" && "$TCP_DUMP" == "1" ]]; then
 68                $ssh "${machines[$i]}" sudo pkill tcpdump >/dev/null 2>&1 || true
 69            fi
 70        ) &
 71    done
 72    wait
 73
 74    echo -e "${YELLOW}Clean Machines${NC}: Base cleanup ${GREEN}Done.${NC}"
 75
 76    if [[ "$PERSISTENCE_SERVICE" == "1" || "$RECORDING_SERVICE" == "1" || "$ROUTING_SERVICE" == "1" ]]; then
 77        echo -e "${YELLOW}Clean Machines${NC}: Cleaning infrastructure services in parallel..."
 78        for ((i = 0 ; i < number_machines ; i++)); do
 79            (
 80                $ssh "${machines[$i]}" pkill rtipersistenc >/dev/null 2>&1 || true
 81                $ssh "${machines[$i]}" pkill rtirecording >/dev/null 2>&1 || true
 82                $ssh "${machines[$i]}" pkill rtirouting >/dev/null 2>&1 || true
 83                # stdout and stderr in tcsh to /dev/null
 84                $ssh "${machines[$i]}" killall -s KILL /bin/bash >/dev/null 2>&1 || true
 85            ) &
 86        done
 87        wait
 88        echo -e "${YELLOW}Clean Machines${NC}: Infrastructure services cleanup ${GREEN}Done.${NC}"
 89
 90    fi
 91    if [[ "${THR_LAT_MODE}" == "THR" ]]; then
 92        for ((i = 0 ; i < number_machines ; i++)); do
 93            echo -e "$INFO_TAG ssh ${machines[$i]} sudo /set_thr_mode.sh &"
 94            $ssh "${machines[$i]}" sudo /set_thr_mode.sh &
 95        done
 96        # Wait for all the background processes to finish
 97        wait
 98    elif [[ "${THR_LAT_MODE}" == "LAT" ]]; then
 99        for ((i = 0 ; i < $number_machines ; i++)); do
100            echo -e "$INFO_TAG ssh ${machines[$i]} sudo /set_lat_mode.sh &"
101            $ssh "${machines[$i]}" sudo /set_lat_mode.sh &
102        done
103        # Wait for all the background processes to finish
104        wait
105    fi
106}
107
108### Reboot Machines:
109
110function reboot_machines () {
111    for ((i = 0 ; i < $number_machines ; i++)); do
112        command="$ssh ${machines[$i]} sudo reboot"
113        echo -e "$INFO_TAG Executing $command"
114        $command
115    done
116}
117
118
119# trap ctrl-c and call ctrl_c()
120trap 'ctrl_c' SIGINT
121
122function ctrl_c() {
123    echo -e " ${RED}TRAPPED CTRL-C !!!!!!!!!!! ${NC}"
124    clean_machines || echo -e "$WARNING_TAG Cleanup skipped due to SSH connectivity failures."
125    killall -s KILL /bin/bash
126}
127
128### Check if I can access via SSH to a machine
129
130function check_ssh_machine() {
131    command="$ssh $1 exit"
132    $command
133    if [[ "$?" == "0" ]]; then
134        echo "true"
135    else
136        echo "false"
137    fi
138}
139
140function validate_ssh_connectivity_all_machines() {
141    local failed_machines=()
142    local failed_machines_file
143    failed_machines_file=$(mktemp)
144
145    echo -e "$INFO_TAG Checking SSH connectivity for all selected machines..."
146    for ((i = 0 ; i < number_machines ; i++)); do
147        (
148            if [[ "$(check_ssh_machine "${machines[$i]}")" != "true" ]]; then
149                echo "${machines[$i]}" >> "$failed_machines_file"
150            fi
151        ) &
152    done
153    wait
154
155    while IFS= read -r failed_machine; do
156        failed_machines+=("$failed_machine")
157    done < "$failed_machines_file"
158    rm -f "$failed_machines_file"
159
160    if [[ "${#failed_machines[@]}" -gt 0 ]]; then
161        echo -e "$ERROR_TAG SSH connectivity check failed for:"
162        for machine in "${failed_machines[@]}"; do
163            echo -e " - ${machine}"
164        done
165        return 1
166    fi
167
168    echo -e "$INFO_TAG SSH connectivity check passed."
169    return 0
170}
171
172function append_ld_library_path_export() {
173    local script_file=$1
174    local lib_path=$2
175
176    if [[ "$NO_LD_PATH_CHECKS" == "1" ]]; then
177        echo -e "export LD_LIBRARY_PATH=${lib_path}:\$LD_LIBRARY_PATH;" >> "$script_file"
178    else
179        echo -e "if [[ -d \"${lib_path}\" ]]; then export LD_LIBRARY_PATH=${lib_path}:\$LD_LIBRARY_PATH; fi" >> "$script_file"
180    fi
181}
182
183### Calculate the perftest executable name and check if exists
184
185function calculate_perftest_binary() {
186    if [[ "$LANGUAGE" == "c++98" ]]; then
187        export perftest_exec="${PERFTESTHOME}/bin/${PLATFORM}/${RELEASE_DEBUG}/perftest_cpp"
188    elif [[ "$LANGUAGE" == "c++11" ]]; then
189        export perftest_exec="${PERFTESTHOME}/bin/${PLATFORM}/${RELEASE_DEBUG}/perftest_cpp11"
190    elif [[ "$LANGUAGE" == "java" ]]; then
191        export perftest_exec="${PERFTESTHOME}/bin/${RELEASE_DEBUG}/perftest_java.sh"
192    elif [[ "$LANGUAGE" == "cs" ]]; then
193        export perftest_exec="${PERFTESTHOME}/bin/${RELEASE_DEBUG}/perftest_cs"
194    fi
195
196    if [[ ! -f $perftest_exec ]]; then
197        echo -e "$ERROR_TAG: The Perftest binary does not exist: $perftest_exec"
198        exit -1
199    fi
200
201    if [[ "$RECORDING_SERVICE" == "1" ]]; then
202        export recording_wrapper_exec="${PERFTESTHOME}/resource/recording_service/recordingservice_wrapper.sh"
203    fi
204
205    if [[ "$ROUTING_SERVICE" == "1" ]]; then
206        export routing_service_exec="${PERFTESTHOME}/resource/routing_service/routingservice_wrapper.sh"
207    fi
208
209    if [[ "$PERSISTENCE_SERVICE" == "1" ]]; then
210        export persistence_service_exec="${PERFTESTHOME}/resource/persistence_service/persistenceService_wrapper.sh"
211    fi
212
213}
214
215### Calculate the folder where to store the results
216
217function calculate_store_folder() {
218
219    export store_point="${PERFTESTNUMBERSHOME}/results/${middleware}/${BRANCH}/network_performance/core/${LANGUAGE}/${TRANSPORT}"
220}
221
222calculate_store_folder
223
224################################################################################
225
226while [ "$1" != "" ]; do
227    case $1 in
228        --nddshome)
229            export NDDSHOME=$2
230            shift
231            ;;
232        --perftest-home)
233            export PERFTESTHOME=$2
234            shift
235            ;;
236        --perftest-numbers-home)
237            export PERFTESTNUMBERSHOME=$2
238            shift
239            ;;
240        --transport)
241            export TRANSPORT=$2
242            shift
243            ;;
244        --arch1 | --platform)
245            export PLATFORM=$2
246            shift
247            ;;
248        --arch2)
249            export ARCH2=$2
250            shift
251            ;;
252        --branch)
253            export BRANCH=$2
254            shift
255            ;;
256        --id)
257            export BUILD_ID=$2
258            shift
259            ;;
260        --openssl-libs)
261            export OPENSSLPATHLIB=$2
262            shift
263            ;;
264        --multicast)
265            export MULTICAST_UNICAST="multicast"
266            ;;
267        --unicast)
268            export MULTICAST_UNICAST="unicast"
269            ;;
270        --best-effort | --be)
271            export BEST_EFFORT="1"
272            ;;
273        --reliable | --rel)
274            export BEST_EFFORT=""
275            ;;
276        --num-publishers)
277            export publishers=$2
278            shift
279            ;;
280        --num-subscribers)
281            export subscribers=$2
282            shift
283            ;;
284        --output-folder)
285            export results_output=$2
286            shift
287            ;;
288        --execution-time)
289            export execution_time=$2
290            shift
291            ;;
292        --data-length | --datalen)
293            export datalen=$2
294            shift
295            ;;
296        --dry)
297            export DRY=1
298            ;;
299        --clean)
300            export CLEAN_MACHINES=1
301            ;;
302        --reboot)
303            reboot_machines
304            exit 0
305            ;;
306        --thr-mode)
307            export THR_LAT_MODE="THR"
308            ;;
309        --lat-mode)
310            export THR_LAT_MODE="LAT"
311            ;;
312        --leave-pub-alone)
313            export PUB_ALONE=1
314            ;;
315        --no-positive-acks)
316            export NO_POS_ACKS=1
317            ;;
318        --security-gov)
319            export SECURITY=1
320            ;;
321        --cft)
322            export CFT=1
323            ;;
324        --instances)
325            export INSTANCES=$2
326            shift
327            ;;
328        --latency-test | --latency)
329            export TEST_KIND="latency"
330            ;;
331        --throughput)
332            export TEST_KIND="throughput"
333            ;;
334        --keyed)
335            export KEYED_UNKEYED="keyed"
336            ;;
337        --unkeyed)
338            export KEYED_UNKEYED="unkeyed"
339            ;;
340        --batch-size)
341            export BATCH_SIZE=$2
342            shift
343            ;;
344        --routing-service)
345            export ROUTING_SERVICE=1
346            ;;
347        --recording-service)
348            export RECORDING_SERVICE=1
349            ;;
350        --persistence-service | --ps)
351            export PERSISTENCE_SERVICE=1
352            ;;
353        --domain-pub)
354            export DOMAIN_PUB=$2
355            shift
356            ;;
357        --domain-sub)
358            export DOMAIN_SUB=$2
359            shift
360            ;;
361        --domain-rec)
362            export DOMAIN_REC=$2
363            shift
364            ;;
365        --domain-rs)
366            export DOMAIN_RS=$2
367            shift
368            ;;
369        --domain-ps)
370            export DOMAIN_PS=$2
371            shift
372            ;;
373        --timeout)
374            export timeout_value=$2
375            shift
376            ;;
377        --durability)
378            export DURABILITY=$2
379            shift
380            ;;
381        --ps-no-direct-communication)
382            export NO_DIRECT_COMMUNICATION=1
383            ;;
384        --test-name)
385            export test_name=$2
386            shift
387            ;;
388        --lab | --lab-file)
389            export LAB_FILE=$2
390            shift
391            ;;
392        --lab-folder)
393            export LAB_FILE="$2/lab.json"
394            shift
395            ;;
396        --machines)
397            export machines_to_use=$2
398            shift
399            ;;
400        --low-jitter-settings)
401            export low_jitter_settings="1"
402            ;;
403        --no-ld-path-checks)
404            export NO_LD_PATH_CHECKS="1"
405            ;;
406        --taskset)
407            export TASKSET_LIST=$2
408            shift
409            ;;
410        *)
411            echo -e "unknown parameter \"$1\""
412            exit -1
413            ;;
414    esac
415    shift
416done
417
418################################################################################
419
420function validate_input() {
421
422
423    if [[ "$LAB_FILE" != "" ]]; then
424        if [ -f "$LAB_FILE" ]; then
425            echo -e "$INFO_TAG Loading lab file $LAB_FILE"
426            export machines=($(jq -r 'to_entries[] | .key' "$LAB_FILE"))
427            export main_interface=($(jq -r 'to_entries[] | .value.main_interface.interface' $LAB_FILE))
428            export main_interface_ip=($(jq -r 'to_entries[] | .value.main_interface.ip' $LAB_FILE))
429            export platforms=($(jq -r 'to_entries[] | .value.architecture' $LAB_FILE))
430            export number_machines=${#machines[@]}
431
432            if [[ "$machines_to_use" != "" ]]; then
433                if ! [[ "$machines_to_use" =~ ^[0-9]+$ ]]; then
434                    echo -e "$ERROR_TAG: --machines must be a positive integer."
435                    exit -1
436                fi
437
438                if [[ "$machines_to_use" -lt "2" ]]; then
439                    echo -e "$ERROR_TAG: --machines must be >= 2."
440                    exit -1
441                fi
442
443                if [[ "$machines_to_use" -gt "$number_machines" ]]; then
444                    echo -e "$ERROR_TAG: --machines ($machines_to_use) cannot be greater than machines in lab file ($number_machines)."
445                    exit -1
446                fi
447
448                machines=("${machines[@]:0:$machines_to_use}")
449                main_interface=("${main_interface[@]:0:$machines_to_use}")
450                main_interface_ip=("${main_interface_ip[@]:0:$machines_to_use}")
451                platforms=("${platforms[@]:0:$machines_to_use}")
452                export number_machines=${#machines[@]}
453            fi
454
455        else
456            echo -e "$ERROR_TAG: The lab file $lab_file does not exist."
457            exit -1
458        fi
459    fi
460
461    if [[ "$CLEAN_MACHINES" == "1" ]]; then
462        if ! clean_machines; then
463            exit -1
464        fi
465        exit 0
466    fi
467
468    # Lets fill up the test information first, either with the defaults or the data.
469
470    if [[ "$PERFTESTNUMBERSHOME" == "" ]]; then
471        export PERFTESTNUMBERSHOME=$repo_location
472    fi
473
474    if [[ "$PERFTESTHOME" == "" ]]; then
475        echo -e "$ERROR_TAG: We need a perftest home"
476        exit -1
477    elif [ ! -d "$PERFTESTHOME" ]; then
478        echo -e "$ERROR_TAG: The Perftest home $PERFTESTHOME does not exist."
479        exit -1
480    fi
481
482    if [[ "$NDDSHOME" == "" ]]; then
483        echo "Setting NDDSHOME to PERFTESTHOME"
484        export NDDSHOME=$PERFTESTHOME
485    fi
486
487    if [[ "$TRANSPORT" == "" ]]; then
488        export TRANSPORT="UDPv4_10Gbps"
489    fi
490
491    if [[ "$LANGUAGE" == "" ]]; then
492        export LANGUAGE="c++98"
493    fi
494
495    if [[ "$RELEASE_DEBUG" == "" ]]; then
496        export RELEASE_DEBUG="release"
497    fi
498
499    if [[ "$PLATFORM" == "" ]]; then
500        export PLATFORM="x64Linux4gcc8.5.0"
501    fi
502
503    if [[ "$ARCH2" != "" ]]; then
504        echo -e "$WARNING_TAG: --arch2 will be ignored and $PLATFORM will be used instead"
505    fi
506    export ARCH2=$PLATFORM
507
508    if [[ "$OPENSSLPATHLIB" == "" ]]; then
509        export OPENSSL1PATHLIB="${NDDSHOME}/third_party/${openssl_1_version}/${PLATFORM}/${RELEASE_DEBUG}/lib"
510        export OPENSSL3PATHLIB="${NDDSHOME}/third_party/${openssl_3_version}/${PLATFORM}/${RELEASE_DEBUG}/lib"
511        export OPENSSL3011PATHLIB="${NDDSHOME}/third_party/${openssl_3011_version}/${PLATFORM}/${RELEASE_DEBUG}/lib"
512        export OPENSSL309PATHLIB="${NDDSHOME}/third_party/${openssl_309_version}/${PLATFORM}/${RELEASE_DEBUG}/lib"
513        export OPENSSL350PATHLIB="${NDDSHOME}/third_party/${openssl_350_version}/${PLATFORM}/${RELEASE_DEBUG}/lib"
514        export OPENSSL355PATHLIB="${NDDSHOME}/third_party/${openssl_355_version}/${PLATFORM}/${RELEASE_DEBUG}/lib"
515        export WOLFSSLPATH_LIB="${NDDSHOME}/third_party/${wolfssl_version}/${PLATFORM}/${RELEASE_DEBUG}/lib"
516    fi
517
518    if [[ "$BEST_EFFORT" == "1" ]]; then
519        export BEST_EFFORT=" -best "
520        export be_string="be"
521    else 
522        export be_string="rel"
523    fi
524
525    calculate_perftest_binary
526    calculate_store_folder
527
528    if [[ "$TASKSET_LIST" != "" ]]; then
529        export taskset_prefix="taskset -c $TASKSET_LIST"
530    else
531        export taskset_prefix=""
532    fi
533
534    if [[ "$publishers" == "" ]]; then
535        export publishers=1
536    fi
537
538    if [[ "$subscribers" == "" ]]; then
539        export subscribers=1
540    fi
541
542    if [[ "${MULTICAST_UNICAST}" == "multicast" ]]; then
543        export USE_MULTICAST="-multicast"
544    fi
545    if [[ "$results_output" == "" ]]; then
546        export results_output="${repo_location}/results/pro/${BRANCH}/${BUILD_ID}/network_performance"
547
548        if [[ "$ROUTING_SERVICE" == "1" ]]; then
549            export results_output="${results_output}/infrastructure_services/routing_service"
550        elif [[ "$RECORDING_SERVICE" == "1" ]]; then
551            export results_output="${results_output}/infrastructure_services/recording_service"
552        elif [[ "$PERSISTENCE_SERVICE" == "1" ]]; then
553            export ps_communication_mode="direct"
554            if [[ "$NO_DIRECT_COMMUNICATION" == "1" ]]; then
555                export ps_communication_mode="no_direct"
556            fi
557            export results_output="${results_output}/infrastructure_services/persistence_service/${ps_communication_mode}"
558        else
559            export results_output="${results_output}/core/${LANGUAGE}/N-M"
560        fi
561
562        export results_output="${results_output}/${TEST_KIND}/${be_string}/${KEYED_UNKEYED}/${MULTICAST_UNICAST}"
563    fi
564
565    if [[ "$execution_time" == "" ]]; then
566        export execution_time=30
567    fi
568
569    if [[ "$datalen" == "" ]]; then
570        export datalen=100
571    fi
572
573    if [[ "$NO_POS_ACKS" == "1" ]]; then
574        export no_positive_acks="-noPositiveAcks"
575        export results_output="${results_output}_no_positive_acks"
576    fi
577
578    if [[ "$KEYED_UNKEYED" == "keyed" ]]; then
579        export keyed_args="-keyed"
580    fi
581
582    if [[ "$INSTANCES" != "" ]]; then
583        export instances_args="-instances $INSTANCES"
584    elif [[ "$KEYED_UNKEYED" == "keyed" ]]; then
585        export instances_args="-instances 200"
586    fi
587
588    if [[ "$CFT" != "" ]]; then
589        export results_output="${results_output}_cft"
590    fi
591
592    export LAT_THR_SCRIPT="/set_thr_mode.sh"
593    export latency_count="-latencyCount 10000"
594    if [[ "$TEST_KIND" == "latency" ]]; then
595        export latency_test="-latencyTest"
596        export latency_count=""
597        export LAT_THR_SCRIPT="/set_lat_mode.sh"
598    fi
599
600    if [[ "$CFT" == "1" ]]; then
601        export instances_args="-instances $subscribers"
602    fi
603
604    export PATH_TO_GOVERNANCE_FILES_FOLDER=$PERFTESTHOME/resource/secure
605
606    if [[ "$SECURITY" == "1" ]]; then
607        export security_params="-secureGovernanceFile $PATH_TO_GOVERNANCE_FILES_FOLDER/signed_PerftestGovernance_RTPSEncrypt.xml"
608    fi
609
610    echo -e "$INFO_TAG: TEST INFO:\n"
611    echo -e " - Perftest home = $PERFTESTHOME"
612    echo -e " - Number of machines = $number_machines"
613    echo -e " - Number of publishers = $publishers"
614    echo -e " - Number of subscribers = $subscribers"
615    echo -e " - OpenSSL Libraries path = $OPENSSLPATHLIB $OPENSSL1PATHLIB $OPENSSL3PATHLIB"
616
617    echo
618
619    export full_test_name="${TRANSPORT}_${be_string}_${publishers}_${subscribers}_${number_machines}"
620    if [[ "$test_name" != "" ]]; then
621        export full_test_name="${test_name}"
622        return
623    fi
624
625}
626
627function main() {
628
629    echo -e "\n=== LAUNCHING PERFORMANCE TESTS ===\n"
630
631    # This function will fill up the environmental variables needed to test
632    validate_input
633
634    export temporal_output=$repo_location/.test/output
635    export temporal_output_files=$repo_location/.test/output_files
636    export temporal_scripts=$repo_location/.test/generated_scripts
637    rm -rf ${temporal_scripts}/*
638    rm -rf ${temporal_output}/*
639    rm -rf ${temporal_output_files}/*
640    mkdir -p $temporal_output
641    mkdir -p $temporal_output_files
642    mkdir -p $temporal_scripts
643    mkdir -p $results_output
644
645    echo -e "\n$INFO_TAG: Cleaning machines before starting the test:"
646    if ! clean_machines; then
647        exit -1
648    fi
649
650    # Generate scripts to run for every perftest
651
652    echo -e "\n$INFO_TAG: GENERATING SCRIPTS:"
653    for ((i = 0 ; i < $number_machines ; i++)); do
654        script_file="${temporal_scripts}/${full_test_name}_${machines[$i]}.sh"
655        output_file="${temporal_output}/${full_test_name}_${machines[$i]}.txt"
656        echo "Creating $script_file"
657        touch $script_file
658        chmod +x $script_file
659        echo -e "#!/bin/bash" >> $script_file
660        if [[ "$THR_LAT_MODE" != "" && "$low_jitter_settings" != "1" ]]; then
661            echo -e "sudo $LAT_THR_SCRIPT" >> $script_file
662            echo -e "sleep 5;" >> $script_file
663        fi
664        echo -e "cd $PERFTESTHOME;" >> $script_file
665        echo -e "export NDDSHOME=${NDDSHOME};" >> $script_file
666        append_ld_library_path_export "$script_file" "${NDDSHOME}/lib/${PLATFORM}"
667        append_ld_library_path_export "$script_file" "${NDDSHOME}/lib/${PLATFORM}/openssl-1.1.1"
668        append_ld_library_path_export "$script_file" "${NDDSHOME}/lib/${PLATFORM}/openssl-3.0"
669        append_ld_library_path_export "$script_file" "${NDDSHOME}/lib/${PLATFORM}/openssl-3.5"
670        append_ld_library_path_export "$script_file" "${NDDSHOME}/lib/${PLATFORM}/wolfssl-5.5"
671        if [[ "$OPENSSLPATHLIB" == "" ]]; then
672            append_ld_library_path_export "$script_file" "${OPENSSL1PATHLIB}"
673            append_ld_library_path_export "$script_file" "${OPENSSL3PATHLIB}"
674            append_ld_library_path_export "$script_file" "${OPENSSL309PATHLIB}"
675            append_ld_library_path_export "$script_file" "${OPENSSL3011PATHLIB}"
676            append_ld_library_path_export "$script_file" "${OPENSSL350PATHLIB}"
677            append_ld_library_path_export "$script_file" "${OPENSSL355PATHLIB}"
678            append_ld_library_path_export "$script_file" "${WOLFSSLPATH_LIB}"
679        else
680            append_ld_library_path_export "$script_file" "${OPENSSLPATHLIB}"
681        fi
682        echo -e "export PERFTEST_BIN=${perftest_exec};" >> $script_file
683
684        if [[ "$RECORDING_SERVICE" == "1" ]]; then
685            echo -e "export RECORDING_WRAPPER=${recording_wrapper_exec};" >> $script_file
686        fi
687
688        if [[ "$ROUTING_SERVICE" == "1" ]]; then
689            echo -e "export ROUTING_WRAPPER=${routing_service_exec};" >> $script_file
690        fi
691
692        if [[ "$PERSISTENCE_SERVICE" == "1" ]]; then
693            echo -e "export PERSISTENCE_SERVICE_WRAPPER=${persistence_service_exec};" >> $script_file
694        fi
695
696        echo -e "touch ${output_file} \\" >> $script_file
697    done
698    echo -e ""
699
700    if [[ "$PUB_ALONE" == "1" ]]; then
701        if [[ "$publishers" -gt "1" ]]; then
702            echo -e "$ERROR_TAG: If you want to have the publisher alone, you can only have one"
703            exit -1
704        fi
705    fi
706
707    for ((i = 0 ; i < $number_machines ; i++)); do
708        machine_status[$i]="None"
709    done
710
711    carried_index=0
712    for ((i = 0 ; i < $publishers ; i++)); do
713        index=$(($i%$number_machines))
714        # echo "i is $i -- index $index"
715        carried_index=$i
716        export script_file="${temporal_scripts}/${full_test_name}_${machines[$index]}.sh"
717        temporal_ouput_file_stderr="${temporal_output_files}/stderr_pub_${full_test_name}_${machines[$index]}_$i.txt"
718        temporal_ouput_file_stout="${temporal_output_files}/stdout_pub_${full_test_name}_${machines[$index]}_$i.csv"
719        export no_headers="-noOutputHeaders"
720        if [[ "$NO_POS_ACKS" == "1" ]]; then
721            export no_positive_acks_string="${no_positive_acks} -initialBurst 80000"
722        fi
723        if [[ "${DOMAIN_PUB}" != "" ]]; then
724            export domain_pub="-domain ${DOMAIN_PUB}"
725        fi
726        if [[ "$DURABILITY" != "" ]]; then
727            export durability="-durability $DURABILITY"
728        fi
729        if [[ "$NO_DIRECT_COMMUNICATION" == "1" ]]; then
730            export no_direct_communication="-noDirectCommunication"
731        fi
732        if [[ "$BATCH_SIZE" != "" ]]; then
733            export batch_size="-batchSize $BATCH_SIZE"
734        fi
735
736        export command="${taskset_prefix} \$PERFTEST_BIN $no_headers -pub -datalen $datalen ${latency_test} ${cft_related_params_pub} \
737            ${keyed_args} ${instances_args} ${domain_pub} ${durability} ${no_direct_communication} ${batch_size} \
738            -transport UDPv4 -nic ${main_interface[$index]} -pid $i -numSubscribers $subscribers ${security_params} \
739            -exec $execution_time ${latency_count} -noPrint -noXML ${no_positive_acks_string} ${USE_MULTICAST} \
740            ${BEST_EFFORT} 2>${temporal_ouput_file_stderr} 1>${temporal_ouput_file_stout} \\"
741        machine_status[$carried_index]="Perftest Publisher"
742        echo -e "&" >> $script_file
743        echo $command >> $script_file
744    done
745
746    carried_index=$(($carried_index+1))
747    for ((i = 0 ; i < $subscribers ; i++)); do
748        carried_i=$(($i+$carried_index))
749        index=$(( ($i+$carried_index) % ($number_machines-1) ))
750        index=$(($index+1))
751        # echo "i is $carried_i -- index $index"
752        export script_file="${temporal_scripts}/${full_test_name}_${machines[$index]}.sh"
753        temporal_ouput_file_stderr="${temporal_output_files}/stderr_sub_${full_test_name}_${machines[$index]}_$i.txt"
754        temporal_ouput_file_stout="${temporal_output_files}/stdout_sub_${full_test_name}_${machines[$index]}_$i.csv"
755        export no_headers="-noOutputHeaders"
756        if [[ "${DOMAIN_SUB}" != "" ]]; then
757            export domain_sub="-domain ${DOMAIN_SUB}"
758        fi
759        if [[ "$CFT" == "1" ]]; then
760            export cft_related_params_sub="-cft $i:$i"
761        fi
762        if [[ "$DURABILITY" != "" ]]; then
763            export durability="-durability $DURABILITY"
764        fi
765        if [[ "$NO_DIRECT_COMMUNICATION" == "1" ]]; then
766            export no_direct_communication="-noDirectCommunication"
767        fi
768        export command="${taskset_prefix} \$PERFTEST_BIN $no_headers -sub -transport UDPv4 -nic ${main_interface[$index]} -sid $i ${cft_related_params_sub} \
769            ${keyed_args} ${instances_args} ${domain_sub} ${durability} ${no_direct_communication} \
770            -numPublishers $publishers -noPrint ${security_params} -noXML ${USE_MULTICAST} ${no_positive_acks} \
771            ${BEST_EFFORT} 2>${temporal_ouput_file_stderr} 1>${temporal_ouput_file_stout} \\"
772        machine_status[$index]="Perftest Subscriber"
773        echo -e "&" >> $script_file
774        echo $command >> $script_file
775    done
776
777    if [[ "$RECORDING_SERVICE" == "1" ]]; then
778        carried_index=$(($carried_index+1))
779        for ((i = 0 ; i < 1 ; i++)); do
780            carried_i=$(($i+$carried_index))
781            index=$(( ($i+$carried_index) % ($number_machines-1) ))
782            index=$(($index+1))
783            # echo "i is $carried_i -- index $index"
784            if [[ "${DOMAIN_REC}" != "" ]]; then
785                export domain_recs="-domain ${DOMAIN_REC}"
786            fi
787            if [[ "$KEYED_UNKEYED" == "keyed" ]]; then
788                export keyed_args="-keyed"
789            fi
790            export script_file="${temporal_scripts}/${full_test_name}_${machines[$index]}.sh"
791            temporal_ouput_file_stderr="${temporal_output_files}/stderr_recording_${full_test_name}_${machines[$index]}_$i.txt"
792            temporal_ouput_file_stout="${temporal_output_files}/stdout_recording_${full_test_name}_${machines[$index]}_$i.csv"
793            execution_time_recording=$(($execution_time+20))
794            export command="\$RECORDING_WRAPPER -executionTime $execution_time_recording -nic ${main_interface[$index]} $domain_recs \
795                ${keyed_args} ${BEST_EFFORT} 2>${temporal_ouput_file_stderr} 1>${temporal_ouput_file_stout} \\"
796            echo -e "&" >> $script_file
797            echo $command >> $script_file
798            machine_status[$index]="recording"
799        done
800    fi
801
802    if [[ "$ROUTING_SERVICE" == "1" ]]; then
803        carried_index=$(($carried_index+1))
804        for ((i = 0 ; i < 1 ; i++)); do
805            carried_i=$(($i+$carried_index))
806            index=$(( ($i+$carried_index) % ($number_machines-1) ))
807            index=$(($index+1))
808            # echo "i is $carried_i -- index $index"
809            if [[ "${DOMAIN_RS}" != "" ]]; then
810                export domain_rs="-domain ${DOMAIN_RS}"
811            fi
812            if [[ "$KEYED_UNKEYED" == "keyed" ]]; then
813                export keyed_args="-keyed"
814            fi
815            export script_file="${temporal_scripts}/${full_test_name}_${machines[$index]}.sh"
816            temporal_ouput_file_stderr="${temporal_output_files}/stderr_routing_${full_test_name}_${machines[$index]}_$i.txt"
817            temporal_ouput_file_stout="${temporal_output_files}/stdout_routing_${full_test_name}_${machines[$index]}_$i.csv"
818            execution_time_routing=$(($execution_time+40))
819            export command="\$ROUTING_WRAPPER -executionTime $execution_time_routing -nic ${main_interface[$index]} $domain_rs \
820                ${keyed_args} ${BEST_EFFORT} 2>${temporal_ouput_file_stderr} 1>${temporal_ouput_file_stout} \\"
821            echo -e "&" >> $script_file
822            echo $command >> $script_file
823            machine_status[$index]="routing"
824        done
825    fi
826
827
828    if [[ "$PERSISTENCE_SERVICE" == "1" ]]; then
829        carried_index=$(($carried_index+1))
830        for ((i = 0 ; i < 1 ; i++)); do
831            carried_i=$(($i+$carried_index))
832            index=$(( ($i+$carried_index) % ($number_machines-1) ))
833            index=$(($index+1))
834            if [[ "${DOMAIN_PS}" != "" ]]; then
835                export domain_ps="-domain ${DOMAIN_PS}"
836            fi
837            if [[ "$KEYED_UNKEYED" == "keyed" ]]; then
838                export keyed_args="-keyed"
839            fi
840            export script_file="${temporal_scripts}/${full_test_name}_${machines[$index]}.sh"
841            temporal_ouput_file_stderr="${temporal_output_files}/stderr_ps_${full_test_name}_${machines[$index]}_$i.txt"
842            temporal_ouput_file_stout="${temporal_output_files}/stdout_ps_${full_test_name}_${machines[$index]}_$i.csv"
843            execution_time_routing=$(($execution_time+40))
844            export command="\$PERSISTENCE_SERVICE_WRAPPER -executionTime $execution_time_routing -nic ${main_interface[$index]} $domain_ps \
845                ${keyed_args} ${BEST_EFFORT} 2>${temporal_ouput_file_stderr} 1>${temporal_ouput_file_stout} \\"
846            echo -e "&" >> $script_file
847            echo $command >> $script_file
848            machine_status[$index]="persistence"
849        done
850    fi
851
852    for ((i = 0 ; i < $number_machines ; i++)); do
853        script_file="${temporal_scripts}/${full_test_name}_${machines[$i]}.sh"
854        output_file="${temporal_output}/${full_test_name}_${machines[$i]}.txt"
855        echo -e ";" >> $script_file
856        echo ${output_file}
857        echo -e "echo -e \"FINISHED $?\" >> ${output_file}" >> $script_file
858        echo -e "echo \"${machines[$i]} OK [${machine_status[$i]}]\"" >> $script_file
859    done
860
861    # If using dry we do not execute anything
862    if [[ "$DRY" == "1" ]]; then
863        echo -e "\n$WARNING_TAG Dry test, leaving now, scripts are written.\n"
864        exit 0
865    fi
866
867    echo -e "\n$INFO_TAG: LAUNCHING TEST:"
868    # ssh to each of the machines executing the command!
869    for ((i = 0 ; i < $number_machines ; i++)); do
870        script_file="${temporal_scripts}/${full_test_name}_${machines[$i]}.sh"
871        export ssh_command="$ssh ${machines[$i]} \"${script_file}\" &"
872        echo -e $ssh_command
873
874        $ssh ${machines[$i]} "${script_file}" &
875    done
876    echo -e "\n"
877
878    sleep 5
879    echo -e "\n$INFO_TAG Test started!!! $full_test_name"
880
881    # Every machine will write a file in $script_location/output, with a single
882    # file, once they finish, if the number of lines is = to the number of participants
883    # that means discovery was completed.
884    sleep 1
885    export found=`cat ${temporal_output}/${full_test_name}_*.txt | wc -l`
886    sleep 5
887    i=5
888    while [ "$found" != "$number_machines" ]; do
889        ((i=i+10))
890        sleep 10
891        echo -e "${GREEN}TEST: $full_test_name ${NC} -- Time: $i s (Found = $found, waiting for $number_machines)."
892        export found=`cat ${temporal_output}/${full_test_name}_*.txt | wc -l`
893        if [[ "$i" -gt "$timeout_value" ]]; then
894            echo -e "$ERROR_TAG: Timeout"
895            clean_machines || echo -e "$WARNING_TAG Cleanup skipped due to SSH connectivity failures."
896            exit 111
897        fi
898    done
899    sleep 2
900
901    # rm -rf  "${results_output}/pub"
902    # rm -rf  "${results_output}/subs"
903    mkdir -p "${results_output}/pub"
904    mkdir -p "${results_output}/subs"
905    export result_file_pubs="${results_output}/pub/${full_test_name}.csv"
906    export result_file_subs="${results_output}/subs/${full_test_name}.csv"
907    touch $result_file_pubs
908    touch $result_file_subs
909
910    echo "Sample Size (Bytes), Ave (μs), Std (μs), Min (μs), Max (μs), 50% (μs), 90% (μs), 99% (μs), 99.99% (μs), 99.9999% (μs)" >> $result_file_pubs
911    echo "Sample Size (Bytes), Total Samples, Avg Samples/s,    Avg Mbps, Lost Samples, Lost Samples (%)" >> $result_file_subs
912    echo -e "$INFO_TAG: Result files are in : $result_file_pubs"
913    cat $temporal_output_files/stdout_pub* >> $result_file_pubs
914    cat $temporal_output_files/stdout_sub* >> $result_file_subs
915
916    awk 'NR==1 {print $0 ", command-line"; next} {print $0 ",command-line not provided"}' "$result_file_pubs" > "${result_file_pubs}.tmp" && mv "${result_file_pubs}.tmp" "$result_file_pubs"
917    awk 'NR==1 {print $0 ", command-line"; next} {print $0 ",command-line not provided"}' "$result_file_subs" > "${result_file_subs}.tmp" && mv "${result_file_subs}.tmp" "$result_file_subs"
918
919    if [[ "$RECORDING_SERVICE" == "1" ]]; then
920        rm -rf  "${results_output}/recording"
921        mkdir -p "${results_output}/recording"
922        export result_file_recording="${results_output}/recording/${full_test_name}.csv"
923        touch $result_file_recording
924        cat $temporal_output_files/stdout_recording* >> $result_file_recording
925    fi
926
927    if [[ "$ROUTING_SERVICE" == "1" ]]; then
928        rm -rf  "${results_output}/routing"
929        mkdir -p "${results_output}/routing"
930        export result_file_routing="${results_output}/routing/${full_test_name}.csv"
931        touch $result_file_routing
932        cat $temporal_output_files/stdout_routing* >> $result_file_routing
933    fi
934
935    if [[ "$PERSISTENCE_SERVICE" == "1" ]]; then
936        rm -rf  "${results_output}/persistence"
937        mkdir -p "${results_output}/persistence"
938        export result_file_persistence="${results_output}/persistence/${full_test_name}.csv"
939        touch $result_file_persistence
940        cat $temporal_output_files/stdout_ps* >> $result_file_persistence
941    fi
942
943    # Merge infrastructure services results into consolidated CSV files
944    if [[ "$ROUTING_SERVICE" == "1" || "$RECORDING_SERVICE" == "1" || "$PERSISTENCE_SERVICE" == "1" ]]; then
945        echo -e "$INFO_TAG Merging infrastructure services results..."
946        export merge_script="${repo_location}/scripts/tools/merge_infrastructure_services_results.py"
947        if [[ -f "$merge_script" ]]; then
948            python3 "$merge_script" "${results_output}"
949        else
950            echo -e "$WARNING_TAG Merge script not found: $merge_script"
951        fi
952    fi
953
954    echo -e "$INFO_TAG Test finished Successfully"
955
956}
957
958main

Test Software

The following software was used to perform these tests:

RTI Connext DDS 7.7.0 Host and Target Libraries for x64 Linux (x64Linux4gcc8.5.0)

Test Hardware

The following hardware was used to perform these tests:

Linux Nodes

Dell R340 Servers (13 Units)
Processor: Intel Xeon E-2278G (3.4-5GHz, 8c/16t, 16MB cache, 2 memory channels @2666MHz)
RAM: 4x 16GB 2666MHz DIMM (64GB RAM)
HD: 480GB SATA SSD
NIC 1: Intel 710 dual port 10Gbps SFP
OS: Ubuntu 24.04 -- gcc 9.3.0

Switch

Dell 2048 -- 10Gbps switch (10Gbps and 1Gbps interfaces)