UDPv4

The following tests have been performed by executing an RTI Perftest C++98 Publisher and Subscriber between two nodes, connected to a switch via Ethernet. The communication has been restricted to a single interface and the transport has been set to UDPv4.

Find information about the hardware, network, and command-line parameters after each of the tests.

Unkeyed, UDPv4 1Gbps Network, C++98

The graph below shows the one-way latency without load between a Publisher and a Subscriber running in two Linux® nodes in a 1Gbps 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.

  • Best Effort

Sample Size (Bytes)

Avg (μs)

Std (μs)

Min (μs)

Max (μs)

50% (μs)

90% (μs)

99% (μs)

99.99% (μs)

99.9999% (μs)

32

52

1.6

48

158

52

55

56

82

158

64

55

1.8

50

118

55

57

58

84

118

128

56

1.6

51

119

56

58

60

85

119

256

61

1.5

56

158

61

63

64

90

158

512

67

1.4

62

125

67

68

70

96

125

1024

80

1.4

75

136

80

81

83

108

136

2048

108

1.2

96

158

108

109

110

136

158

4096

160

1.3

154

212

160

161

163

188

212

8192

265

1.5

258

318

265

267

268

295

318

16384

341

1.5

336

397

341

343

344

371

397

32768

474

1.4

467

536

474

475

476

503

536

63000

735

1.6

728

802

735

737

738

766

802

  • Reliable

Sample Size (Bytes)

Avg (μs)

Std (μs)

Min (μs)

Max (μs)

50% (μs)

90% (μs)

99% (μs)

99.99% (μs)

99.9999% (μs)

32

55

2.2

47

118

56

57

61

84

118

64

57

1.6

48

105

57

59

62

86

105

128

58

1.8

50

121

58

60

63

88

121

256

64

1.4

57

123

63

65

67

92

123

512

69

1.5

64

129

68

70

73

98

129

1024

82

1.5

76

138

82

84

86

111

138

2048

109

1.4

104

161

109

111

114

138

161

4096

162

1.3

156

211

162

163

166

191

211

8192

267

1.5

261

320

267

268

271

295

320

16384

343

1.5

337

398

343

345

346

374

398

32768

475

1.5

468

535

475

477

478

505

535

63000

737

1.7

730

804

737

738

741

772

804

100000

1044

3.9

1037

1140

1043

1050

1055

1140

1140

500000

4314

10.6

4306

4616

4312

4316

4360

4616

4616

1048576

8798

33.6

8774

9348

8795

8806

8912

9348

9348

1548576

12887

30.7

12865

13655

12885

12887

12906

13655

13655

4194304

34644

117.7

34616

36420

34633

34641

34672

36420

36420

10485760

86671

417.8

86603

90632

86616

86627

88726

90632

90632


Perftest Scripts

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

  1#!/bin/bash
  2filename=$0
  3script_location=$(cd "$(dirname "$filename")" || exit 255; pwd)
  4
  5export datasizes="32 64 128 256 512 1024 2048 4096 8192 16384 32768 63000"
  6export datasizes_extended="${datasizes} 100000 500000 1048576 1548576 4194304 10485760"
  7
  8export domain="2"
  9export exec_time=20
 10export num_reps=1
 11export instance_number=100000
 12export core=0
 13export run_batching_tests="1"
 14export run_no_batching_tests="1"
 15
 16# We will use some colors to improve visibility of errors and info messages.
 17RED='\033[0;31m'
 18GREEN='\033[0;32m'
 19YELLOW='\033[0;33m'
 20BLUE='\033[0;34m'
 21LIGHTBLUE='\033[0;36m'
 22NC='\033[0m'
 23INFO_TAG="${GREEN}[INFO][$role]:${NC}"
 24WARNING_TAG="${YELLOW}[WARNING][$role]:${NC}"
 25ERROR_TAG="${RED}[ERROR][$role]:${NC}"
 26
 27################################################################################
 28
 29function disable_colors() {
 30    export RED=""
 31    export GREEN=""
 32    export YELLOW=""
 33    export NC=""
 34    export BLUE=""
 35    export LIGHTBLUE=""
 36    export INFO_TAG="${GREEN}[INFO][$role]:${NC}"
 37    export WARNING_TAG="${YELLOW}[WARNING][$role]:${NC}"
 38    export ERROR_TAG="${RED}[ERROR][$role]:${NC}"
 39}
 40
 41function change_domain() {
 42    if [[ "$domain" == "1" ]]; then
 43        export domain="2"
 44    else
 45        export domain="1"
 46    fi
 47}
 48
 49# Function to process and append lines to the output file
 50function append_to_output_file() {
 51    local line=${1?line required}; readonly line
 52    local append=$(echo "${2?append required}" | tr -s ' '); readonly append
 53    local file=${3?file required}; readonly file
 54    if [[ "${line: -1}" == $'\n' ]]; then
 55        line="${line::-1}"
 56    fi
 57    echo "${line}${append}" >> "$file"
 58}
 59
 60# Usage: execute_test <keyed/unkeyed> <rel/be> <datasizes> <batchSize>
 61function execute_test() {
 62
 63    local keyed_unkeyed=$1
 64    local rel_be=$2
 65    local datasizes_test=$3
 66    local other_args=$4
 67    local name_suffix=$5
 68
 69    local commands_string_test=$commands_string
 70    local tag=""
 71
 72    if [[ "${keyed_unkeyed}" == "keyed" ]]; then
 73        commands_string_test="${commands_string_test} -keyed -instances $instance_number"
 74        tag="[${YELLOW}${transport}${NC}|${BLUE}K${NC}|"
 75    else
 76        tag="[${YELLOW}${transport}${NC}|${LIGHTBLUE}UK${NC}|"
 77    fi
 78
 79    if [[ "${rel_be}" == "be" ]]; then
 80        commands_string_test="${commands_string_test} -bestEffort"
 81        tag="${tag}${YELLOW}BE${NC}]"
 82    else
 83        tag="${tag}${RED}REL${NC}]"
 84    fi
 85
 86    # If batch_size is set, we will add it to the command line of the publisher side.
 87    if [[ "$batch_size" != "" && "$role" == "pub" ]]; then
 88        commands_string_test="${commands_string_test} -batchSize $batch_size"
 89    fi
 90
 91    tag="${tag}[${LIGHTBLUE}${lat_thr}${NC}]"
 92
 93    local output_file=$output_folder/${lat_thr}_${role}_${keyed_unkeyed}_${rel_be}${name_suffix}.csv
 94
 95    if [[ "$role" == "pub" ]]; then
 96        echo -e "${YELLOW}[TEST]: $keyed_unkeyed, $rel_be, Is a no-batching test = $no_batching_tests. ${NC}"
 97    fi
 98
 99    if [[ "$thread_cpu_affinity" != "" ]]; then
100        commands_string_test="${commands_string_test} -threadCPUAffinity $thread_cpu_affinity"
101    fi
102
103    local pre_command_string=""
104
105    if [[ "$thread_priorities" != "" ]]; then
106        echo -e "${WARNING_TAG} Thread priorities enabled, this requires using sudo"
107        # When using sudo, the LD_LIBRARY_PATH is emptied, hence we need to set it again in the command itself
108        export LD_LIBRARY_PATH_COPIED="$LD_LIBRARY_PATH"
109        pre_command_string="sudo LD_LIBRARY_PATH=$LD_LIBRARY_PATH_COPIED "
110        commands_string_test="${commands_string_test} -threadPriorities $thread_priorities"
111    fi
112
113    if [[ "$pin_memory" != "" ]]; then
114        commands_string_test="${commands_string_test} -pinMemory"
115    fi
116
117    if [[ "$no_taskset" == "" && "$thread_cpu_affinity" == "" && "$LANGUAGE" != "java" && "$LANGUAGE" != "cs" ]]; then
118        pre_command_string="$pre_command_string taskset -c $core"
119    fi
120
121    if [[ "$LANGUAGE" == "python" ]]; then
122        pre_command_string="$pre_command_string python3 "
123    fi
124
125    if [[ "$DOCKER" == "1" ]]; then
126        pre_command_string="$pre_command_string docker run --net=host -v /home/perfuser/rti_license_connextpro.dat:/opt/rti.com/rti_connext_dds-7.3.0/rti_license.dat rticom/perftest:7.3.0-EAR "
127        executable=""
128    fi
129
130    # Get the aprox time this will take:
131    total_tests=$((`wc -w <<< "$datasizes_test"` * num_reps))
132    total_time=$((total_tests * exec_time))
133
134    touch $output_file
135    local no_headers=""
136    local current_test=0
137    for index in $(seq 1 ${num_reps}); do
138        for DATALEN in ${datasizes_test}; do
139            current_test=$((current_test + 1))
140
141            if [[ ! -s $output_file ]]; then
142                echo -e "${INFO_TAG} Output file is empty, filling the header."
143                no_headers=""
144            else
145                echo -e "${INFO_TAG} Output file is not empty."
146                no_headers=" -noOutputHeaders"
147            fi
148
149            export command="$pre_command_string $executable -domain $domain -dataLen $DATALEN $commands_string_test $other_args $no_headers"
150            if [[ "$role" == "pub" ]]; then
151                echo -e "Test ${tag} (${current_test}/${total_tests}) -- Total time = ${total_time}s"
152                echo -e ${BLUE}$command${NC}
153            else
154                echo -e ${LIGHTBLUE}$command${NC}
155            fi
156
157            # In certain cases we need to wait a bit before running the test, this is
158            # because the previous test might not be finished on the other side yet, or because the
159            # discovery mechanism does not work like in connext DDS.
160            if [[ "$LANGUAGE" == "cs" && "$role" == "pub" ]]; then
161                sleep 3
162            fi
163            if [[ "$raw" == "1" && "$role" == "sub" ]]; then
164                sleep 5
165            fi
166
167            # Gather netstat info before running the test
168            if [[ "${get_netstat_info}" == "1" ]]; then
169                echo -e "${INFO_TAG} Getting netstat info before"
170                netstat -s -u | grep -e "error" -e "packet" > $output_folder/${lat_thr}_${role}_${keyed_unkeyed}_${rel_be}${name_suffix}_netstat_before.txt
171            fi
172
173            # Execute the command and capture the output
174            if [[ $LANGUAGE == "c++98" || $LANGUAGE == "" ]]; then
175                echo -e "${INFO_TAG} Using C++98, using -outputFile option"
176                touch ${output_file}_tmp_line
177                chmod 777 ${output_file}_tmp_line
178                eval $command -outputFile ${output_file}_tmp_line
179            else
180                eval $command > ${output_file}_tmp_line
181            fi
182
183            number_of_lines=$(wc -l < ${output_file}_tmp_line)
184            echo -e "${INFO_TAG} Size of the output text: $number_of_lines lines"
185
186            # Check if this is the first test for this output file.
187            local is_first_test=0
188            if [[ ! -s $output_file ]]; then
189                is_first_test=1
190            fi
191            local expected_lines=$((is_first_test+1))
192
193            if [[ $number_of_lines -ne ${expected_lines} ]]; then
194                echo -e "${WARNING_TAG} The output text should have ${expected_lines} lines, but it has ${number_of_lines}."
195                echo -e "${RED} The content is: \n\"\"\""
196                cat ${output_file}_tmp_line
197                echo -e "\"\"\""
198                echo -e "Not adding it to the output file. ${NC}"
199            else
200                if [[ $number_of_lines -gt 1 ]]; then
201                    header_line=$(head -n 1 "${output_file}_tmp_line")
202                    echo -e "${INFO_TAG} Header line is: $header_line"
203                fi
204                result_line=$(tail -n 1 "${output_file}_tmp_line")
205                echo -e "${INFO_TAG} Result line is: $result_line"
206
207                # If this is the first test, we need to add the header line to the output file
208                if [[ $is_first_test -eq 1 ]]; then
209                    append_to_output_file "$header_line" ", command-line" $output_file
210                fi
211
212                command=$(echo $command | sed 's/,/:comma:/g')
213                # Remove the `"` characters from the command line
214                command=$(echo $command | sed 's/\"//g')
215
216                # Append the result line to the output file
217                append_to_output_file "$result_line" ", $command" $output_file
218            fi
219
220            # Always remove the temporary file
221            rm -rf ${output_file}_tmp_line
222
223            # Gather netstat info after running the test
224            if [[ "${get_netstat_info}" == "1" ]]; then
225                echo -e "${INFO_TAG} Getting netstat info after"
226                netstat -s -u | grep -e "error" -e "packet" > $output_folder/${lat_thr}_${role}_${keyed_unkeyed}_${rel_be}${name_suffix}_netstat_after.txt
227                touch "$output_folder/${lat_thr}_${role}_${keyed_unkeyed}_${rel_be}${name_suffix}_netstat.csv"
228                python3 $script_location/../../../tools/diff_netstat_output.py \
229                    -n $output_folder/${lat_thr}_${role}_${keyed_unkeyed}_${rel_be}${name_suffix}_netstat_after.txt \
230                    -o $output_folder/${lat_thr}_${role}_${keyed_unkeyed}_${rel_be}${name_suffix}_netstat_before.txt \
231                    -d $DATALEN $no_header_netstat \
232                    -csv >> "$output_folder/${lat_thr}_${role}_${keyed_unkeyed}_${rel_be}${name_suffix}_netstat.csv"
233                rm -rf $output_folder/${lat_thr}_${role}_${keyed_unkeyed}_${rel_be}${name_suffix}_netstat_*.txt
234                no_header_netstat=" -nh"
235            fi
236
237            change_domain
238        done
239    done
240}
241
242################################################################################
243# PARSE COMMAND LINE OPTIONS:
244
245while [ "$1" != "" ]; do
246    case $1 in
247        --executable)
248            executable=$2
249            shift
250            ;;
251        --docker)
252            DOCKER="1"
253            ;;
254        --output-folder)
255            output_folder=$2
256            shift
257            ;;
258        --role)
259            export role=$2
260            shift
261            ;;
262        --core)
263            export core=$2
264            shift
265            ;;
266        --assign-core-list | --thread-cpu-affinity)
267            export thread_cpu_affinity=$2
268            shift
269            ;;
270        --assign-thread-priorities | --thread-priorities)
271            export thread_priorities=$2
272            shift
273            ;;
274        --pin-memory)
275            export pin_memory="1"
276            ;;
277        --test-kind)
278            export lat_thr=$2
279            shift
280            ;;
281        --interface1)
282            export interface=$2
283            shift
284            ;;
285        --interface2)
286            export interface2=$2
287            shift
288            ;;
289        --ip1)
290            export ip1=$2
291            shift
292            ;;
293        --ip2)
294            export ip2=$2
295            shift
296            ;;
297        --repetitions)
298            export num_reps=$2
299            shift
300            ;;
301        --domain)
302            export domain=$2
303            shift
304            ;;
305        --execution-time)
306            export exec_time=$2
307            shift
308            ;;
309        --transport)
310            export transport=$2
311            shift
312            ;;
313        --datalen)
314            export datalen_input=$2
315            shift
316            ;;
317        --file-suffix)
318            export file_suffix=$2
319            shift
320            ;;
321        --folder-suffix)
322            export folder_suffix=$2
323            shift
324            ;;
325        --sub-folder)
326            sub_folder=$2
327            shift
328            ;;
329        --executable-suffix)
330            export executable_suffix=$2
331            shift
332            ;;
333        --extra-arguments)
334            export extra_arguments=$2
335            shift
336            ;;
337        --extra-arguments-pub)
338            export extra_arguments_pub=$2
339            shift
340            ;;
341        --extra-arguments-sub)
342            export extra_arguments_sub=$2
343            shift
344            ;;
345        --skip-be)
346            export skip_be_tests="1"
347            ;;
348        --skip-rel)
349            export skip_rel_tests="1"
350            ;;
351        --skip-keyed)
352            export skip_keyed_data="1"
353            ;;
354        --skip-large-data)
355            export skip_large_data="1"
356            ;;
357        --large-data)
358            export large_data="1"
359            ;;
360        --keyed)
361            export skip_unkeyed="1"
362            ;;
363        --unkeyed)
364            export skip_keyed_data="1"
365            ;;
366        --no-batching | --skip-batching)
367            export run_batching_tests="0"
368            export run_no_batching_tests="1"
369            ;;
370        --skip-no-batching)
371            export run_batching_tests="1"
372            export run_no_batching_tests="0"
373            ;;
374        --batch-size)
375            export batch_size=$2
376            shift
377            ;;
378        --reliable)
379            export skip_be_tests="1"
380            ;;
381        --best-effort)
382            export skip_rel_tests="1"
383            ;;
384        --security-gov)
385            export security_only="$2"
386            shift
387            ;;
388        --micro)
389            export micro="1"
390            ;;
391        --cert)
392            export cert="1"
393            ;;
394        --raw | --raw-transport)
395            export raw="1"
396            ;;
397        --tss)
398            export tss="1"
399            ;;
400        --no-colors)
401            export NO_COLORS="1"
402            ;;
403        --language)
404            export LANGUAGE=$2
405            shift
406            ;;
407        --loss-rate)
408            export loss_rate=$2
409            shift
410            ;;
411        --get-netstat-info | --netstat)
412            export get_netstat_info="1"
413            ;;
414        --reduced-data-sizes-set)
415            export REDUCED_DATA_SIZES_SET="1"
416            ;;
417        --dont-change-tuned-settings)
418            export dont_change_tuned_settings="1"
419            ;;
420        --no-taskset)
421            export no_taskset=1
422            ;;
423        *)
424            echo -e "unknown parameter \"$1\""
425            exit 255
426            ;;
427    esac
428    shift
429done
430
431if [[ "$NO_COLORS" == "1" ]]; then
432    disable_colors
433fi
434
435export folder_base="$(dirname "${executable}")"/../../..
436
437if [[ $LANGUAGE == "java"  || "$LANGUAGE" == "cs" ]]; then
438    export folder_base="$(dirname "${executable}")"/../..
439fi
440if [[ $tss == "1" ]]; then
441    export folder_base="$(dirname "${executable}")"/../../../../..
442fi
443
444if [[ "${executable_suffix}" != "" ]]; then
445    export executable="${executable}${executable_suffix}"
446fi
447
448if [[ -n "${folder_suffix}" ]]; then
449    export output_folder="${output_folder}${folder_suffix}"
450fi
451
452if [[ -n "${sub_folder}" ]]; then
453    export output_folder="${output_folder}/${sub_folder}"
454fi
455
456echo -e "${INFO_TAG} Perftest executable is: $executable"
457echo -e "${INFO_TAG} Output folder is: $output_folder"
458
459################################################################################
460
461if [[ "$LANGUAGE" == "python" ]]; then
462    export skip_keyed_data="1"
463    export skip_large_data="1"
464    export skip_be_tests="1"
465    export run_no_batching_tests="0"
466fi
467
468if [[ "${skip_large_data}" == "1" ]]; then
469    export datasizes_extended=${datasizes}
470elif [[ "${large_data}" == "1" ]]; then
471    export datasizes=${datasizes_extended}
472fi
473
474if [[ "${datalen_input}" != "" ]]; then
475    echo -e "${YELLOW}[TEST] Testing only for ${datalen_input}${NC}"
476    export datasizes=${datalen_input}
477    export datasizes_extended=${datalen_input}
478    if [[ "${run_no_batching_tests}" == "1" && "${run_batching_tests}" == "0" ]]; then
479        export skip_large_data="1"
480    fi
481else 
482    if [[ "${REDUCED_DATA_SIZES_SET}" != "" ]]; then
483        echo -e "${YELLOW}[TEST] Testing Reduced set of datasizes ${NC}"
484        export datasizes="32 128 512 2048 8192 32768 63000"
485        export datasizes_extended="${datasizes} 102400 1048576 10485760"
486    fi
487fi
488
489if [[ "$role" != "pub" && "$role" != "sub" ]]; then
490    echo -e "${ERROR_TAG} It must be either publisher or subscriber"
491    exit 255
492fi
493
494if [[ "$lat_thr" != "thr" && "$lat_thr" != "lat" ]]; then
495    echo -e "${ERROR_TAG} It must be either lat or thr"
496    exit 255
497fi
498
499if [[ "${interface}" == "" ]]; then
500    echo "Using default nics"
501    export nic_publisher=${ip_machine_1}
502    export nic_subscriber=${ip_machine_2}
503elif [[ "${interface}" == "both" ]]; then
504    export nic_publisher="enp1s0f0,eno1"
505    export nic_subscriber="enp1s0f0,eno1"
506    echo -e "${INFO_TAG} Using nic_publisher: ${nic_publisher}"
507    echo -e "${INFO_TAG} Using nic_subscriber: ${nic_subscriber}"
508else
509    export nic_publisher=$interface
510    echo -e "${INFO_TAG} Using nic_publisher: ${nic_publisher}"
511
512    if [[ "${interface2}" == "" ]]; then
513        export nic_subscriber=$interface
514    else
515        export nic_subscriber=$interface2
516    fi
517    echo -e "${INFO_TAG} Using nic_subscriber: ${nic_subscriber}"
518
519    if [[ "${ip1}" != "" ]]; then
520        export ip_publisher=$ip1
521        echo "Using ip_publisher: ${ip_publisher}"
522    fi
523
524    if [[ "${ip2}" != "" ]]; then
525        export ip_subscriber=$ip2
526        echo "Using ip_subscriber: ${ip_subscriber}"
527    fi
528
529fi
530
531export transport_string="-transport $transport"
532
533if [[ "$transport" == "UDPv4" ]]; then
534
535    export transport_string_pub="$transport_string -nic $nic_publisher"
536    export transport_string_sub="$transport_string -nic $nic_subscriber"
537
538    if [[ "$raw" == "1" ]]; then
539        export transport_string_pub="$transport_string_pub -peer ${ip_subscriber}"
540        export transport_string_sub="$transport_string_sub -peer ${ip_publisher}"
541    fi
542
543    if [[ "$micro" == "1" || "$cert" == "1" ]]; then
544        export transport_string_pub="$transport_string_pub -peer _udp://${ip_subscriber}"
545        export transport_string_sub="$transport_string_sub -peer _udp://${ip_publisher}"
546    fi
547
548elif [[ "$transport" == "TCP" ]]; then
549    export transport_string_pub="$transport_string \
550        -nic $nic_publisher \
551        -peer 0@tcpv4_lan://${ip_subscriber}:7400"
552    export transport_string_sub="$transport_string \
553        -nic $nic_subscriber \
554        -peer 0@tcpv4_lan://${ip_publisher}:7400"
555elif [[ "$transport" == "TLS" ]]; then
556    export transport_string_pub="$transport_string \
557        -nic $nic_publisher \
558        -peer tlsv4_lan://${ip_subscriber}:7400"
559    export transport_string_sub="$transport_string \
560        -nic $nic_subscriber \
561        -peer tlsv4_lan://${ip_publisher}:7400"
562elif [[ "$transport" == "UDPv4_WAN" ]]; then
563    export transport_string_pub="$transport_string \
564        -nic $nic_publisher \
565        -transportPublicAddress $ip_publisher:7400"
566    export transport_string_sub="$transport_string \
567        -nic $nic_subscriber \
568        -peer 0@udpv4_wan://${ip_publisher}:7400"
569else
570    export transport_string_pub="$transport_string"
571    export transport_string_sub="$transport_string"
572fi
573
574################################################################################
575
576export pub_string="-pub \
577        ${transport_string_pub} \
578        -noPrintIntervals \
579        -executionTime $exec_time"
580
581if [[ ${lat_thr} == "lat" ]]; then
582    export pub_string="$pub_string \
583        -latencyTest"
584fi
585
586export sub_string="-sub \
587        ${transport_string_sub} \
588        -noPrintIntervals"
589
590if [[ "$role" == "pub" ]]; then
591    echo -e "$INFO_TAG Publisher side running"
592    export commands_string=${pub_string}
593    export extra_arguments="${extra_arguments} ${extra_arguments_pub}"
594else
595    echo -e "$INFO_TAG Subscriber side running"
596    export commands_string=${sub_string}
597    export extra_arguments="${extra_arguments} ${extra_arguments_sub}"
598fi
599
600###############################################################################
601
602if [[ "$dont_change_tuned_settings" != "1" ]]; then
603    echo -e "${INFO_TAG} Executing: /set_${lat_thr}_mode.sh"
604    sudo /set_${lat_thr}_mode.sh
605    sleep 5
606fi
607
608echo -e "${INFO_TAG} Disabling any loss rate"
609sudo tc qdisc add dev $nic_publisher root netem loss 0%
610sudo tc qdisc del dev $nic_publisher root netem loss 0%
611
612if [[ "$role" == "pub" && "${loss_rate}" != "" ]]; then
613    echo -e "${INFO_TAG} Setting loss rate to ${loss_rate}%"
614    sudo tc qdisc add dev $nic_publisher root netem loss $loss_rate%
615fi
616
617cd $folder_base
618echo -e "${INFO_TAG} Folder Base is: $PWD"
619mkdir -p $output_folder
620
621if [[ "${batch_size}" != "" ]]; then
622    if [[ "${lat_thr}" == "thr" ]]; then
623        if [[ "${batch_size}" -eq 0 ]]; then
624            echo -e "${INFO_TAG} Batch size is set to 0"
625            export run_batching_tests="0"
626            export run_no_batching_tests="1"
627        else
628            echo -e "${INFO_TAG} Batch size is set to ${batch_size}"
629            export run_batching_tests="1"
630            export run_no_batching_tests="0"
631        fi
632    else
633        echo -e "${INFO_TAG} Batch size is set to ${batch_size}. This value will be ignored for latency tests."
634        unset batch_size
635    fi
636fi
637
638# Tests that may use batching (when doing throughput tests). Also Latency tests.
639if [[ ${run_batching_tests} == "1" ]]; then
640
641    # UNKEYED
642    if [[ "${skip_unkeyed}" == "" ]]; then
643
644        # RELIABLE
645        if [[ "${skip_rel_tests}" == "" ]]; then
646            execute_test "unkeyed" "rel" "${datasizes_extended}" "${extra_arguments}" "$file_suffix"
647        fi
648
649        # BEST EFFORT
650        if [[ "${skip_be_tests}" == "" ]]; then
651            execute_test "unkeyed" "be" "${datasizes}" "${extra_arguments}" "$file_suffix"
652        fi
653    fi
654
655    # KEYED
656    if [[ "${skip_keyed_data}" == "" ]]; then
657
658        # RELIABLE
659        if [[ "${skip_rel_tests}" == "" ]]; then
660            execute_test "keyed" "rel" "${datasizes}" "${extra_arguments}" "$file_suffix"
661        fi
662
663        # BEST EFFORT
664        if [[ "${skip_be_tests}" == "" ]]; then
665            execute_test "keyed" "be" "${datasizes}" "${extra_arguments}" "$file_suffix"
666        fi
667    fi
668
669fi
670
671# Tests that will not use batching
672if [[ "${lat_thr}" == "thr" && "${run_no_batching_tests}" == "1" ]]; then
673
674    if [[ "$role" == "pub" ]]; then
675        export commands_string="${commands_string} -batchSize 0"
676    fi
677
678    # UNKEYED
679    if [[ "${skip_unkeyed}" == "" ]]; then
680
681        # RELIABLE
682        if [[ "${skip_rel_tests}" == "" ]]; then
683            execute_test "unkeyed" "rel" "${datasizes}" "${extra_arguments}" "_noBatch${file_suffix}"
684        fi
685
686        # BEST EFFORT
687        if [[ "${skip_be_tests}" == "" ]]; then
688            execute_test "unkeyed" "be" "${datasizes}" "${extra_arguments}" "_noBatch${file_suffix}"
689        fi
690    fi
691
692    # KEYED
693    if [[ "${skip_keyed_data}" == "" ]]; then
694
695        # RELIABLE
696        if [[ "${skip_rel_tests}" == "" ]]; then
697            execute_test "keyed" "rel" "${datasizes}" "${extra_arguments}" "_noBatch${file_suffix}"
698        fi
699
700        # BEST EFFORT
701        if [[ "${skip_be_tests}" == "" ]]; then
702            execute_test "keyed" "be" "${datasizes}" "${extra_arguments}" "_noBatch${file_suffix}"
703        fi
704    fi
705
706fi
707
708if [[ "$role" == "pub" && "${loss_rate}" != "" ]]; then
709    echo -e "${INFO_TAG} Disabling loss rate"
710    sudo tc qdisc del dev $nic_publisher root netem loss $loss_rate%
711fi
1#!/bin/bash
2filename=$0
3script_location=$(cd "$(dirname "$filename")" || exit 255; pwd)
4
5echo -e "[Calling base_script/script.sh]"
6"${script_location}/../base_script/script.sh" $@ --transport UDPv4

Test Software

The following software was used to perform these tests:

RTI Connext DDS 6.1.1 Host and Target Libraries for x64 Linux (x64Linux4gcc7.3.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 20.04 -- gcc 9.3.0

Switch

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

Unkeyed, UDPv4 10Gbps Network, C++98

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.

  • Best Effort

Sample Size (Bytes)

Ave (μs)

Std (μs)

Min (μs)

Max (μs)

50% (μs)

90% (μs)

99% (μs)

99.99% (μs)

99.9999% (μs)

32

15

132.0

14

100050

15

15

16

44

100050

64

15

0.9

14

64

15

16

17

44

64

128

15

1.0

15

65

15

16

17

45

65

256

15

1.0

14

73

15

15

16

44

73

512

19

1.9

15

69

19

21

22

47

69

1024

25

3.3

17

64

26

28

29

53

64

2048

32

194.2

18

100076

30

55

69

80

100076

4096

32

131.3

23

100058

30

34

54

69

100058

8192

40

8.7

33

89

34

55

62

77

89

16384

83

22.5

44

173

82

118

131

143

173

32768

172

2.2

65

216

172

173

174

201

216

63000

183

2.7

99

213

183

185

186

212

213

  • Reliable

Sample Size (Bytes)

Ave (μs)

Std (μs)

Min (μs)

Max (μs)

50% (μs)

90% (μs)

99% (μs)

99.99% (μs)

99.9999% (μs)

32

16

1.0

15

96

16

17

20

46

96

64

17

1.1

16

68

16

17

21

46

68

128

17

1.3

16

67

16

17

23

46

67

256

17

2.1

16

64

17

19

28

46

64

512

20

3.0

17

70

19

21

32

49

70

1024

25

4.8

18

85

26

29

39

57

85

2048

29

31.9

20

4917

30

33

44

68

4917

4096

31

18.1

24

4235

30

36

48

68

4235

8192

41

26.6

34

5016

36

57

65

82

5016

16384

86

25.3

45

161

85

123

136

146

161

32768

171

8.0

74

203

173

174

176

202

203

63000

169

15.0

104

223

167

186

188

215

223

100000

205

9.2

154

254

208

210

216

241

254

500000

619

32.6

504

2920

619

651

697

1011

2920

1048576

1180

43.9

1069

1683

1204

1207

1224

1683

1683

1548576

1704

20.5

1541

2331

1701

1730

1752

2331

2331

4194304

4052

47.9

4010

6083

4047

4073

4099

6083

6083

10485760

10185

166.8

10152

15009

10177

10188

10211

15009

15009


Perftest Scripts

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

  1#!/bin/bash
  2filename=$0
  3script_location=$(cd "$(dirname "$filename")" || exit 255; pwd)
  4
  5export datasizes="32 64 128 256 512 1024 2048 4096 8192 16384 32768 63000"
  6export datasizes_extended="${datasizes} 100000 500000 1048576 1548576 4194304 10485760"
  7
  8export domain="2"
  9export exec_time=20
 10export num_reps=1
 11export instance_number=100000
 12export core=0
 13export run_batching_tests="1"
 14export run_no_batching_tests="1"
 15
 16# We will use some colors to improve visibility of errors and info messages.
 17RED='\033[0;31m'
 18GREEN='\033[0;32m'
 19YELLOW='\033[0;33m'
 20BLUE='\033[0;34m'
 21LIGHTBLUE='\033[0;36m'
 22NC='\033[0m'
 23INFO_TAG="${GREEN}[INFO][$role]:${NC}"
 24WARNING_TAG="${YELLOW}[WARNING][$role]:${NC}"
 25ERROR_TAG="${RED}[ERROR][$role]:${NC}"
 26
 27################################################################################
 28
 29function disable_colors() {
 30    export RED=""
 31    export GREEN=""
 32    export YELLOW=""
 33    export NC=""
 34    export BLUE=""
 35    export LIGHTBLUE=""
 36    export INFO_TAG="${GREEN}[INFO][$role]:${NC}"
 37    export WARNING_TAG="${YELLOW}[WARNING][$role]:${NC}"
 38    export ERROR_TAG="${RED}[ERROR][$role]:${NC}"
 39}
 40
 41function change_domain() {
 42    if [[ "$domain" == "1" ]]; then
 43        export domain="2"
 44    else
 45        export domain="1"
 46    fi
 47}
 48
 49# Function to process and append lines to the output file
 50function append_to_output_file() {
 51    local line=${1?line required}; readonly line
 52    local append=$(echo "${2?append required}" | tr -s ' '); readonly append
 53    local file=${3?file required}; readonly file
 54    if [[ "${line: -1}" == $'\n' ]]; then
 55        line="${line::-1}"
 56    fi
 57    echo "${line}${append}" >> "$file"
 58}
 59
 60# Usage: execute_test <keyed/unkeyed> <rel/be> <datasizes> <batchSize>
 61function execute_test() {
 62
 63    local keyed_unkeyed=$1
 64    local rel_be=$2
 65    local datasizes_test=$3
 66    local other_args=$4
 67    local name_suffix=$5
 68
 69    local commands_string_test=$commands_string
 70    local tag=""
 71
 72    if [[ "${keyed_unkeyed}" == "keyed" ]]; then
 73        commands_string_test="${commands_string_test} -keyed -instances $instance_number"
 74        tag="[${YELLOW}${transport}${NC}|${BLUE}K${NC}|"
 75    else
 76        tag="[${YELLOW}${transport}${NC}|${LIGHTBLUE}UK${NC}|"
 77    fi
 78
 79    if [[ "${rel_be}" == "be" ]]; then
 80        commands_string_test="${commands_string_test} -bestEffort"
 81        tag="${tag}${YELLOW}BE${NC}]"
 82    else
 83        tag="${tag}${RED}REL${NC}]"
 84    fi
 85
 86    # If batch_size is set, we will add it to the command line of the publisher side.
 87    if [[ "$batch_size" != "" && "$role" == "pub" ]]; then
 88        commands_string_test="${commands_string_test} -batchSize $batch_size"
 89    fi
 90
 91    tag="${tag}[${LIGHTBLUE}${lat_thr}${NC}]"
 92
 93    local output_file=$output_folder/${lat_thr}_${role}_${keyed_unkeyed}_${rel_be}${name_suffix}.csv
 94
 95    if [[ "$role" == "pub" ]]; then
 96        echo -e "${YELLOW}[TEST]: $keyed_unkeyed, $rel_be, Is a no-batching test = $no_batching_tests. ${NC}"
 97    fi
 98
 99    if [[ "$thread_cpu_affinity" != "" ]]; then
100        commands_string_test="${commands_string_test} -threadCPUAffinity $thread_cpu_affinity"
101    fi
102
103    local pre_command_string=""
104
105    if [[ "$thread_priorities" != "" ]]; then
106        echo -e "${WARNING_TAG} Thread priorities enabled, this requires using sudo"
107        # When using sudo, the LD_LIBRARY_PATH is emptied, hence we need to set it again in the command itself
108        export LD_LIBRARY_PATH_COPIED="$LD_LIBRARY_PATH"
109        pre_command_string="sudo LD_LIBRARY_PATH=$LD_LIBRARY_PATH_COPIED "
110        commands_string_test="${commands_string_test} -threadPriorities $thread_priorities"
111    fi
112
113    if [[ "$pin_memory" != "" ]]; then
114        commands_string_test="${commands_string_test} -pinMemory"
115    fi
116
117    if [[ "$no_taskset" == "" && "$thread_cpu_affinity" == "" && "$LANGUAGE" != "java" && "$LANGUAGE" != "cs" ]]; then
118        pre_command_string="$pre_command_string taskset -c $core"
119    fi
120
121    if [[ "$LANGUAGE" == "python" ]]; then
122        pre_command_string="$pre_command_string python3 "
123    fi
124
125    if [[ "$DOCKER" == "1" ]]; then
126        pre_command_string="$pre_command_string docker run --net=host -v /home/perfuser/rti_license_connextpro.dat:/opt/rti.com/rti_connext_dds-7.3.0/rti_license.dat rticom/perftest:7.3.0-EAR "
127        executable=""
128    fi
129
130    # Get the aprox time this will take:
131    total_tests=$((`wc -w <<< "$datasizes_test"` * num_reps))
132    total_time=$((total_tests * exec_time))
133
134    touch $output_file
135    local no_headers=""
136    local current_test=0
137    for index in $(seq 1 ${num_reps}); do
138        for DATALEN in ${datasizes_test}; do
139            current_test=$((current_test + 1))
140
141            if [[ ! -s $output_file ]]; then
142                echo -e "${INFO_TAG} Output file is empty, filling the header."
143                no_headers=""
144            else
145                echo -e "${INFO_TAG} Output file is not empty."
146                no_headers=" -noOutputHeaders"
147            fi
148
149            export command="$pre_command_string $executable -domain $domain -dataLen $DATALEN $commands_string_test $other_args $no_headers"
150            if [[ "$role" == "pub" ]]; then
151                echo -e "Test ${tag} (${current_test}/${total_tests}) -- Total time = ${total_time}s"
152                echo -e ${BLUE}$command${NC}
153            else
154                echo -e ${LIGHTBLUE}$command${NC}
155            fi
156
157            # In certain cases we need to wait a bit before running the test, this is
158            # because the previous test might not be finished on the other side yet, or because the
159            # discovery mechanism does not work like in connext DDS.
160            if [[ "$LANGUAGE" == "cs" && "$role" == "pub" ]]; then
161                sleep 3
162            fi
163            if [[ "$raw" == "1" && "$role" == "sub" ]]; then
164                sleep 5
165            fi
166
167            # Gather netstat info before running the test
168            if [[ "${get_netstat_info}" == "1" ]]; then
169                echo -e "${INFO_TAG} Getting netstat info before"
170                netstat -s -u | grep -e "error" -e "packet" > $output_folder/${lat_thr}_${role}_${keyed_unkeyed}_${rel_be}${name_suffix}_netstat_before.txt
171            fi
172
173            # Execute the command and capture the output
174            if [[ $LANGUAGE == "c++98" || $LANGUAGE == "" ]]; then
175                echo -e "${INFO_TAG} Using C++98, using -outputFile option"
176                touch ${output_file}_tmp_line
177                chmod 777 ${output_file}_tmp_line
178                eval $command -outputFile ${output_file}_tmp_line
179            else
180                eval $command > ${output_file}_tmp_line
181            fi
182
183            number_of_lines=$(wc -l < ${output_file}_tmp_line)
184            echo -e "${INFO_TAG} Size of the output text: $number_of_lines lines"
185
186            # Check if this is the first test for this output file.
187            local is_first_test=0
188            if [[ ! -s $output_file ]]; then
189                is_first_test=1
190            fi
191            local expected_lines=$((is_first_test+1))
192
193            if [[ $number_of_lines -ne ${expected_lines} ]]; then
194                echo -e "${WARNING_TAG} The output text should have ${expected_lines} lines, but it has ${number_of_lines}."
195                echo -e "${RED} The content is: \n\"\"\""
196                cat ${output_file}_tmp_line
197                echo -e "\"\"\""
198                echo -e "Not adding it to the output file. ${NC}"
199            else
200                if [[ $number_of_lines -gt 1 ]]; then
201                    header_line=$(head -n 1 "${output_file}_tmp_line")
202                    echo -e "${INFO_TAG} Header line is: $header_line"
203                fi
204                result_line=$(tail -n 1 "${output_file}_tmp_line")
205                echo -e "${INFO_TAG} Result line is: $result_line"
206
207                # If this is the first test, we need to add the header line to the output file
208                if [[ $is_first_test -eq 1 ]]; then
209                    append_to_output_file "$header_line" ", command-line" $output_file
210                fi
211
212                command=$(echo $command | sed 's/,/:comma:/g')
213                # Remove the `"` characters from the command line
214                command=$(echo $command | sed 's/\"//g')
215
216                # Append the result line to the output file
217                append_to_output_file "$result_line" ", $command" $output_file
218            fi
219
220            # Always remove the temporary file
221            rm -rf ${output_file}_tmp_line
222
223            # Gather netstat info after running the test
224            if [[ "${get_netstat_info}" == "1" ]]; then
225                echo -e "${INFO_TAG} Getting netstat info after"
226                netstat -s -u | grep -e "error" -e "packet" > $output_folder/${lat_thr}_${role}_${keyed_unkeyed}_${rel_be}${name_suffix}_netstat_after.txt
227                touch "$output_folder/${lat_thr}_${role}_${keyed_unkeyed}_${rel_be}${name_suffix}_netstat.csv"
228                python3 $script_location/../../../tools/diff_netstat_output.py \
229                    -n $output_folder/${lat_thr}_${role}_${keyed_unkeyed}_${rel_be}${name_suffix}_netstat_after.txt \
230                    -o $output_folder/${lat_thr}_${role}_${keyed_unkeyed}_${rel_be}${name_suffix}_netstat_before.txt \
231                    -d $DATALEN $no_header_netstat \
232                    -csv >> "$output_folder/${lat_thr}_${role}_${keyed_unkeyed}_${rel_be}${name_suffix}_netstat.csv"
233                rm -rf $output_folder/${lat_thr}_${role}_${keyed_unkeyed}_${rel_be}${name_suffix}_netstat_*.txt
234                no_header_netstat=" -nh"
235            fi
236
237            change_domain
238        done
239    done
240}
241
242################################################################################
243# PARSE COMMAND LINE OPTIONS:
244
245while [ "$1" != "" ]; do
246    case $1 in
247        --executable)
248            executable=$2
249            shift
250            ;;
251        --docker)
252            DOCKER="1"
253            ;;
254        --output-folder)
255            output_folder=$2
256            shift
257            ;;
258        --role)
259            export role=$2
260            shift
261            ;;
262        --core)
263            export core=$2
264            shift
265            ;;
266        --assign-core-list | --thread-cpu-affinity)
267            export thread_cpu_affinity=$2
268            shift
269            ;;
270        --assign-thread-priorities | --thread-priorities)
271            export thread_priorities=$2
272            shift
273            ;;
274        --pin-memory)
275            export pin_memory="1"
276            ;;
277        --test-kind)
278            export lat_thr=$2
279            shift
280            ;;
281        --interface1)
282            export interface=$2
283            shift
284            ;;
285        --interface2)
286            export interface2=$2
287            shift
288            ;;
289        --ip1)
290            export ip1=$2
291            shift
292            ;;
293        --ip2)
294            export ip2=$2
295            shift
296            ;;
297        --repetitions)
298            export num_reps=$2
299            shift
300            ;;
301        --domain)
302            export domain=$2
303            shift
304            ;;
305        --execution-time)
306            export exec_time=$2
307            shift
308            ;;
309        --transport)
310            export transport=$2
311            shift
312            ;;
313        --datalen)
314            export datalen_input=$2
315            shift
316            ;;
317        --file-suffix)
318            export file_suffix=$2
319            shift
320            ;;
321        --folder-suffix)
322            export folder_suffix=$2
323            shift
324            ;;
325        --sub-folder)
326            sub_folder=$2
327            shift
328            ;;
329        --executable-suffix)
330            export executable_suffix=$2
331            shift
332            ;;
333        --extra-arguments)
334            export extra_arguments=$2
335            shift
336            ;;
337        --extra-arguments-pub)
338            export extra_arguments_pub=$2
339            shift
340            ;;
341        --extra-arguments-sub)
342            export extra_arguments_sub=$2
343            shift
344            ;;
345        --skip-be)
346            export skip_be_tests="1"
347            ;;
348        --skip-rel)
349            export skip_rel_tests="1"
350            ;;
351        --skip-keyed)
352            export skip_keyed_data="1"
353            ;;
354        --skip-large-data)
355            export skip_large_data="1"
356            ;;
357        --large-data)
358            export large_data="1"
359            ;;
360        --keyed)
361            export skip_unkeyed="1"
362            ;;
363        --unkeyed)
364            export skip_keyed_data="1"
365            ;;
366        --no-batching | --skip-batching)
367            export run_batching_tests="0"
368            export run_no_batching_tests="1"
369            ;;
370        --skip-no-batching)
371            export run_batching_tests="1"
372            export run_no_batching_tests="0"
373            ;;
374        --batch-size)
375            export batch_size=$2
376            shift
377            ;;
378        --reliable)
379            export skip_be_tests="1"
380            ;;
381        --best-effort)
382            export skip_rel_tests="1"
383            ;;
384        --security-gov)
385            export security_only="$2"
386            shift
387            ;;
388        --micro)
389            export micro="1"
390            ;;
391        --cert)
392            export cert="1"
393            ;;
394        --raw | --raw-transport)
395            export raw="1"
396            ;;
397        --tss)
398            export tss="1"
399            ;;
400        --no-colors)
401            export NO_COLORS="1"
402            ;;
403        --language)
404            export LANGUAGE=$2
405            shift
406            ;;
407        --loss-rate)
408            export loss_rate=$2
409            shift
410            ;;
411        --get-netstat-info | --netstat)
412            export get_netstat_info="1"
413            ;;
414        --reduced-data-sizes-set)
415            export REDUCED_DATA_SIZES_SET="1"
416            ;;
417        --dont-change-tuned-settings)
418            export dont_change_tuned_settings="1"
419            ;;
420        --no-taskset)
421            export no_taskset=1
422            ;;
423        *)
424            echo -e "unknown parameter \"$1\""
425            exit 255
426            ;;
427    esac
428    shift
429done
430
431if [[ "$NO_COLORS" == "1" ]]; then
432    disable_colors
433fi
434
435export folder_base="$(dirname "${executable}")"/../../..
436
437if [[ $LANGUAGE == "java"  || "$LANGUAGE" == "cs" ]]; then
438    export folder_base="$(dirname "${executable}")"/../..
439fi
440if [[ $tss == "1" ]]; then
441    export folder_base="$(dirname "${executable}")"/../../../../..
442fi
443
444if [[ "${executable_suffix}" != "" ]]; then
445    export executable="${executable}${executable_suffix}"
446fi
447
448if [[ -n "${folder_suffix}" ]]; then
449    export output_folder="${output_folder}${folder_suffix}"
450fi
451
452if [[ -n "${sub_folder}" ]]; then
453    export output_folder="${output_folder}/${sub_folder}"
454fi
455
456echo -e "${INFO_TAG} Perftest executable is: $executable"
457echo -e "${INFO_TAG} Output folder is: $output_folder"
458
459################################################################################
460
461if [[ "$LANGUAGE" == "python" ]]; then
462    export skip_keyed_data="1"
463    export skip_large_data="1"
464    export skip_be_tests="1"
465    export run_no_batching_tests="0"
466fi
467
468if [[ "${skip_large_data}" == "1" ]]; then
469    export datasizes_extended=${datasizes}
470elif [[ "${large_data}" == "1" ]]; then
471    export datasizes=${datasizes_extended}
472fi
473
474if [[ "${datalen_input}" != "" ]]; then
475    echo -e "${YELLOW}[TEST] Testing only for ${datalen_input}${NC}"
476    export datasizes=${datalen_input}
477    export datasizes_extended=${datalen_input}
478    if [[ "${run_no_batching_tests}" == "1" && "${run_batching_tests}" == "0" ]]; then
479        export skip_large_data="1"
480    fi
481else 
482    if [[ "${REDUCED_DATA_SIZES_SET}" != "" ]]; then
483        echo -e "${YELLOW}[TEST] Testing Reduced set of datasizes ${NC}"
484        export datasizes="32 128 512 2048 8192 32768 63000"
485        export datasizes_extended="${datasizes} 102400 1048576 10485760"
486    fi
487fi
488
489if [[ "$role" != "pub" && "$role" != "sub" ]]; then
490    echo -e "${ERROR_TAG} It must be either publisher or subscriber"
491    exit 255
492fi
493
494if [[ "$lat_thr" != "thr" && "$lat_thr" != "lat" ]]; then
495    echo -e "${ERROR_TAG} It must be either lat or thr"
496    exit 255
497fi
498
499if [[ "${interface}" == "" ]]; then
500    echo "Using default nics"
501    export nic_publisher=${ip_machine_1}
502    export nic_subscriber=${ip_machine_2}
503elif [[ "${interface}" == "both" ]]; then
504    export nic_publisher="enp1s0f0,eno1"
505    export nic_subscriber="enp1s0f0,eno1"
506    echo -e "${INFO_TAG} Using nic_publisher: ${nic_publisher}"
507    echo -e "${INFO_TAG} Using nic_subscriber: ${nic_subscriber}"
508else
509    export nic_publisher=$interface
510    echo -e "${INFO_TAG} Using nic_publisher: ${nic_publisher}"
511
512    if [[ "${interface2}" == "" ]]; then
513        export nic_subscriber=$interface
514    else
515        export nic_subscriber=$interface2
516    fi
517    echo -e "${INFO_TAG} Using nic_subscriber: ${nic_subscriber}"
518
519    if [[ "${ip1}" != "" ]]; then
520        export ip_publisher=$ip1
521        echo "Using ip_publisher: ${ip_publisher}"
522    fi
523
524    if [[ "${ip2}" != "" ]]; then
525        export ip_subscriber=$ip2
526        echo "Using ip_subscriber: ${ip_subscriber}"
527    fi
528
529fi
530
531export transport_string="-transport $transport"
532
533if [[ "$transport" == "UDPv4" ]]; then
534
535    export transport_string_pub="$transport_string -nic $nic_publisher"
536    export transport_string_sub="$transport_string -nic $nic_subscriber"
537
538    if [[ "$raw" == "1" ]]; then
539        export transport_string_pub="$transport_string_pub -peer ${ip_subscriber}"
540        export transport_string_sub="$transport_string_sub -peer ${ip_publisher}"
541    fi
542
543    if [[ "$micro" == "1" || "$cert" == "1" ]]; then
544        export transport_string_pub="$transport_string_pub -peer _udp://${ip_subscriber}"
545        export transport_string_sub="$transport_string_sub -peer _udp://${ip_publisher}"
546    fi
547
548elif [[ "$transport" == "TCP" ]]; then
549    export transport_string_pub="$transport_string \
550        -nic $nic_publisher \
551        -peer 0@tcpv4_lan://${ip_subscriber}:7400"
552    export transport_string_sub="$transport_string \
553        -nic $nic_subscriber \
554        -peer 0@tcpv4_lan://${ip_publisher}:7400"
555elif [[ "$transport" == "TLS" ]]; then
556    export transport_string_pub="$transport_string \
557        -nic $nic_publisher \
558        -peer tlsv4_lan://${ip_subscriber}:7400"
559    export transport_string_sub="$transport_string \
560        -nic $nic_subscriber \
561        -peer tlsv4_lan://${ip_publisher}:7400"
562elif [[ "$transport" == "UDPv4_WAN" ]]; then
563    export transport_string_pub="$transport_string \
564        -nic $nic_publisher \
565        -transportPublicAddress $ip_publisher:7400"
566    export transport_string_sub="$transport_string \
567        -nic $nic_subscriber \
568        -peer 0@udpv4_wan://${ip_publisher}:7400"
569else
570    export transport_string_pub="$transport_string"
571    export transport_string_sub="$transport_string"
572fi
573
574################################################################################
575
576export pub_string="-pub \
577        ${transport_string_pub} \
578        -noPrintIntervals \
579        -executionTime $exec_time"
580
581if [[ ${lat_thr} == "lat" ]]; then
582    export pub_string="$pub_string \
583        -latencyTest"
584fi
585
586export sub_string="-sub \
587        ${transport_string_sub} \
588        -noPrintIntervals"
589
590if [[ "$role" == "pub" ]]; then
591    echo -e "$INFO_TAG Publisher side running"
592    export commands_string=${pub_string}
593    export extra_arguments="${extra_arguments} ${extra_arguments_pub}"
594else
595    echo -e "$INFO_TAG Subscriber side running"
596    export commands_string=${sub_string}
597    export extra_arguments="${extra_arguments} ${extra_arguments_sub}"
598fi
599
600###############################################################################
601
602if [[ "$dont_change_tuned_settings" != "1" ]]; then
603    echo -e "${INFO_TAG} Executing: /set_${lat_thr}_mode.sh"
604    sudo /set_${lat_thr}_mode.sh
605    sleep 5
606fi
607
608echo -e "${INFO_TAG} Disabling any loss rate"
609sudo tc qdisc add dev $nic_publisher root netem loss 0%
610sudo tc qdisc del dev $nic_publisher root netem loss 0%
611
612if [[ "$role" == "pub" && "${loss_rate}" != "" ]]; then
613    echo -e "${INFO_TAG} Setting loss rate to ${loss_rate}%"
614    sudo tc qdisc add dev $nic_publisher root netem loss $loss_rate%
615fi
616
617cd $folder_base
618echo -e "${INFO_TAG} Folder Base is: $PWD"
619mkdir -p $output_folder
620
621if [[ "${batch_size}" != "" ]]; then
622    if [[ "${lat_thr}" == "thr" ]]; then
623        if [[ "${batch_size}" -eq 0 ]]; then
624            echo -e "${INFO_TAG} Batch size is set to 0"
625            export run_batching_tests="0"
626            export run_no_batching_tests="1"
627        else
628            echo -e "${INFO_TAG} Batch size is set to ${batch_size}"
629            export run_batching_tests="1"
630            export run_no_batching_tests="0"
631        fi
632    else
633        echo -e "${INFO_TAG} Batch size is set to ${batch_size}. This value will be ignored for latency tests."
634        unset batch_size
635    fi
636fi
637
638# Tests that may use batching (when doing throughput tests). Also Latency tests.
639if [[ ${run_batching_tests} == "1" ]]; then
640
641    # UNKEYED
642    if [[ "${skip_unkeyed}" == "" ]]; then
643
644        # RELIABLE
645        if [[ "${skip_rel_tests}" == "" ]]; then
646            execute_test "unkeyed" "rel" "${datasizes_extended}" "${extra_arguments}" "$file_suffix"
647        fi
648
649        # BEST EFFORT
650        if [[ "${skip_be_tests}" == "" ]]; then
651            execute_test "unkeyed" "be" "${datasizes}" "${extra_arguments}" "$file_suffix"
652        fi
653    fi
654
655    # KEYED
656    if [[ "${skip_keyed_data}" == "" ]]; then
657
658        # RELIABLE
659        if [[ "${skip_rel_tests}" == "" ]]; then
660            execute_test "keyed" "rel" "${datasizes}" "${extra_arguments}" "$file_suffix"
661        fi
662
663        # BEST EFFORT
664        if [[ "${skip_be_tests}" == "" ]]; then
665            execute_test "keyed" "be" "${datasizes}" "${extra_arguments}" "$file_suffix"
666        fi
667    fi
668
669fi
670
671# Tests that will not use batching
672if [[ "${lat_thr}" == "thr" && "${run_no_batching_tests}" == "1" ]]; then
673
674    if [[ "$role" == "pub" ]]; then
675        export commands_string="${commands_string} -batchSize 0"
676    fi
677
678    # UNKEYED
679    if [[ "${skip_unkeyed}" == "" ]]; then
680
681        # RELIABLE
682        if [[ "${skip_rel_tests}" == "" ]]; then
683            execute_test "unkeyed" "rel" "${datasizes}" "${extra_arguments}" "_noBatch${file_suffix}"
684        fi
685
686        # BEST EFFORT
687        if [[ "${skip_be_tests}" == "" ]]; then
688            execute_test "unkeyed" "be" "${datasizes}" "${extra_arguments}" "_noBatch${file_suffix}"
689        fi
690    fi
691
692    # KEYED
693    if [[ "${skip_keyed_data}" == "" ]]; then
694
695        # RELIABLE
696        if [[ "${skip_rel_tests}" == "" ]]; then
697            execute_test "keyed" "rel" "${datasizes}" "${extra_arguments}" "_noBatch${file_suffix}"
698        fi
699
700        # BEST EFFORT
701        if [[ "${skip_be_tests}" == "" ]]; then
702            execute_test "keyed" "be" "${datasizes}" "${extra_arguments}" "_noBatch${file_suffix}"
703        fi
704    fi
705
706fi
707
708if [[ "$role" == "pub" && "${loss_rate}" != "" ]]; then
709    echo -e "${INFO_TAG} Disabling loss rate"
710    sudo tc qdisc del dev $nic_publisher root netem loss $loss_rate%
711fi
1#!/bin/bash
2filename=$0
3script_location=$(cd "$(dirname "$filename")" || exit 255; pwd)
4
5echo -e "[Calling base_script/script.sh]"
6"${script_location}/../base_script/script.sh" $@ --transport UDPv4

Test Software

The following software was used to perform these tests:

RTI Connext DDS 6.1.2 Host and Target Libraries for x64 Linux (x64Linux4gcc7.3.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 20.04 -- gcc 9.3.0

Switch

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

Keyed, UDPv4 1Gbps Network, C++98

The graph below shows the one-way latency without load between a Publisher and a Subscriber running in two Linux nodes in a 1Gbps 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.

  • Best Effort

Sample Size (Bytes)

Avg (μs)

Std (μs)

Min (μs)

Max (μs)

50% (μs)

90% (μs)

99% (μs)

99.99% (μs)

99.9999% (μs)

32

58

1.7

53

207

58

60

62

88

207

64

59

1.6

54

209

59

61

62

89

209

128

61

1.7

55

208

61

62

64

90

208

256

65

1.3

60

213

65

66

68

94

213

512

71

1.5

64

216

70

72

73

99

216

1024

84

1.4

78

236

84

85

87

114

236

2048

111

1.4

105

255

111

112

114

142

255

4096

164

1.5

158

311

163

165

167

194

311

8192

269

1.7

262

414

269

270

273

299

414

16384

345

1.8

338

490

345

347

348

382

490

32768

478

1.9

471

624

478

479

481

519

624

63000

739

2.1

731

883

739

740

742

810

883

  • Reliable

Sample Size (Bytes)

Avg (μs)

Std (μs)

Min (μs)

Max (μs)

50% (μs)

90% (μs)

99% (μs)

99.99% (μs)

99.9999% (μs)

32

61

1.7

54

206

60

62

66

89

206

64

61

1.8

55

208

61

63

66

91

208

128

63

1.6

57

212

62

64

68

92

212

256

67

1.5

61

217

67

68

71

96

217

512

73

1.6

67

221

72

74

78

102

221

1024

86

1.7

80

234

85

87

91

115

234

2048

113

1.5

107

188

113

115

118

142

188

4096

166

1.5

158

236

165

167

170

195

236

8192

271

1.6

265

326

271

272

275

303

326

16384

347

1.6

341

405

347

348

350

376

405

32768

479

1.5

472

541

479

481

482

507

541

63000

740

1.9

734

813

740

742

744

772

813


Perftest Scripts

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

  1#!/bin/bash
  2filename=$0
  3script_location=$(cd "$(dirname "$filename")" || exit 255; pwd)
  4
  5export datasizes="32 64 128 256 512 1024 2048 4096 8192 16384 32768 63000"
  6export datasizes_extended="${datasizes} 100000 500000 1048576 1548576 4194304 10485760"
  7
  8export domain="2"
  9export exec_time=20
 10export num_reps=1
 11export instance_number=100000
 12export core=0
 13export run_batching_tests="1"
 14export run_no_batching_tests="1"
 15
 16# We will use some colors to improve visibility of errors and info messages.
 17RED='\033[0;31m'
 18GREEN='\033[0;32m'
 19YELLOW='\033[0;33m'
 20BLUE='\033[0;34m'
 21LIGHTBLUE='\033[0;36m'
 22NC='\033[0m'
 23INFO_TAG="${GREEN}[INFO][$role]:${NC}"
 24WARNING_TAG="${YELLOW}[WARNING][$role]:${NC}"
 25ERROR_TAG="${RED}[ERROR][$role]:${NC}"
 26
 27################################################################################
 28
 29function disable_colors() {
 30    export RED=""
 31    export GREEN=""
 32    export YELLOW=""
 33    export NC=""
 34    export BLUE=""
 35    export LIGHTBLUE=""
 36    export INFO_TAG="${GREEN}[INFO][$role]:${NC}"
 37    export WARNING_TAG="${YELLOW}[WARNING][$role]:${NC}"
 38    export ERROR_TAG="${RED}[ERROR][$role]:${NC}"
 39}
 40
 41function change_domain() {
 42    if [[ "$domain" == "1" ]]; then
 43        export domain="2"
 44    else
 45        export domain="1"
 46    fi
 47}
 48
 49# Function to process and append lines to the output file
 50function append_to_output_file() {
 51    local line=${1?line required}; readonly line
 52    local append=$(echo "${2?append required}" | tr -s ' '); readonly append
 53    local file=${3?file required}; readonly file
 54    if [[ "${line: -1}" == $'\n' ]]; then
 55        line="${line::-1}"
 56    fi
 57    echo "${line}${append}" >> "$file"
 58}
 59
 60# Usage: execute_test <keyed/unkeyed> <rel/be> <datasizes> <batchSize>
 61function execute_test() {
 62
 63    local keyed_unkeyed=$1
 64    local rel_be=$2
 65    local datasizes_test=$3
 66    local other_args=$4
 67    local name_suffix=$5
 68
 69    local commands_string_test=$commands_string
 70    local tag=""
 71
 72    if [[ "${keyed_unkeyed}" == "keyed" ]]; then
 73        commands_string_test="${commands_string_test} -keyed -instances $instance_number"
 74        tag="[${YELLOW}${transport}${NC}|${BLUE}K${NC}|"
 75    else
 76        tag="[${YELLOW}${transport}${NC}|${LIGHTBLUE}UK${NC}|"
 77    fi
 78
 79    if [[ "${rel_be}" == "be" ]]; then
 80        commands_string_test="${commands_string_test} -bestEffort"
 81        tag="${tag}${YELLOW}BE${NC}]"
 82    else
 83        tag="${tag}${RED}REL${NC}]"
 84    fi
 85
 86    # If batch_size is set, we will add it to the command line of the publisher side.
 87    if [[ "$batch_size" != "" && "$role" == "pub" ]]; then
 88        commands_string_test="${commands_string_test} -batchSize $batch_size"
 89    fi
 90
 91    tag="${tag}[${LIGHTBLUE}${lat_thr}${NC}]"
 92
 93    local output_file=$output_folder/${lat_thr}_${role}_${keyed_unkeyed}_${rel_be}${name_suffix}.csv
 94
 95    if [[ "$role" == "pub" ]]; then
 96        echo -e "${YELLOW}[TEST]: $keyed_unkeyed, $rel_be, Is a no-batching test = $no_batching_tests. ${NC}"
 97    fi
 98
 99    if [[ "$thread_cpu_affinity" != "" ]]; then
100        commands_string_test="${commands_string_test} -threadCPUAffinity $thread_cpu_affinity"
101    fi
102
103    local pre_command_string=""
104
105    if [[ "$thread_priorities" != "" ]]; then
106        echo -e "${WARNING_TAG} Thread priorities enabled, this requires using sudo"
107        # When using sudo, the LD_LIBRARY_PATH is emptied, hence we need to set it again in the command itself
108        export LD_LIBRARY_PATH_COPIED="$LD_LIBRARY_PATH"
109        pre_command_string="sudo LD_LIBRARY_PATH=$LD_LIBRARY_PATH_COPIED "
110        commands_string_test="${commands_string_test} -threadPriorities $thread_priorities"
111    fi
112
113    if [[ "$pin_memory" != "" ]]; then
114        commands_string_test="${commands_string_test} -pinMemory"
115    fi
116
117    if [[ "$no_taskset" == "" && "$thread_cpu_affinity" == "" && "$LANGUAGE" != "java" && "$LANGUAGE" != "cs" ]]; then
118        pre_command_string="$pre_command_string taskset -c $core"
119    fi
120
121    if [[ "$LANGUAGE" == "python" ]]; then
122        pre_command_string="$pre_command_string python3 "
123    fi
124
125    if [[ "$DOCKER" == "1" ]]; then
126        pre_command_string="$pre_command_string docker run --net=host -v /home/perfuser/rti_license_connextpro.dat:/opt/rti.com/rti_connext_dds-7.3.0/rti_license.dat rticom/perftest:7.3.0-EAR "
127        executable=""
128    fi
129
130    # Get the aprox time this will take:
131    total_tests=$((`wc -w <<< "$datasizes_test"` * num_reps))
132    total_time=$((total_tests * exec_time))
133
134    touch $output_file
135    local no_headers=""
136    local current_test=0
137    for index in $(seq 1 ${num_reps}); do
138        for DATALEN in ${datasizes_test}; do
139            current_test=$((current_test + 1))
140
141            if [[ ! -s $output_file ]]; then
142                echo -e "${INFO_TAG} Output file is empty, filling the header."
143                no_headers=""
144            else
145                echo -e "${INFO_TAG} Output file is not empty."
146                no_headers=" -noOutputHeaders"
147            fi
148
149            export command="$pre_command_string $executable -domain $domain -dataLen $DATALEN $commands_string_test $other_args $no_headers"
150            if [[ "$role" == "pub" ]]; then
151                echo -e "Test ${tag} (${current_test}/${total_tests}) -- Total time = ${total_time}s"
152                echo -e ${BLUE}$command${NC}
153            else
154                echo -e ${LIGHTBLUE}$command${NC}
155            fi
156
157            # In certain cases we need to wait a bit before running the test, this is
158            # because the previous test might not be finished on the other side yet, or because the
159            # discovery mechanism does not work like in connext DDS.
160            if [[ "$LANGUAGE" == "cs" && "$role" == "pub" ]]; then
161                sleep 3
162            fi
163            if [[ "$raw" == "1" && "$role" == "sub" ]]; then
164                sleep 5
165            fi
166
167            # Gather netstat info before running the test
168            if [[ "${get_netstat_info}" == "1" ]]; then
169                echo -e "${INFO_TAG} Getting netstat info before"
170                netstat -s -u | grep -e "error" -e "packet" > $output_folder/${lat_thr}_${role}_${keyed_unkeyed}_${rel_be}${name_suffix}_netstat_before.txt
171            fi
172
173            # Execute the command and capture the output
174            if [[ $LANGUAGE == "c++98" || $LANGUAGE == "" ]]; then
175                echo -e "${INFO_TAG} Using C++98, using -outputFile option"
176                touch ${output_file}_tmp_line
177                chmod 777 ${output_file}_tmp_line
178                eval $command -outputFile ${output_file}_tmp_line
179            else
180                eval $command > ${output_file}_tmp_line
181            fi
182
183            number_of_lines=$(wc -l < ${output_file}_tmp_line)
184            echo -e "${INFO_TAG} Size of the output text: $number_of_lines lines"
185
186            # Check if this is the first test for this output file.
187            local is_first_test=0
188            if [[ ! -s $output_file ]]; then
189                is_first_test=1
190            fi
191            local expected_lines=$((is_first_test+1))
192
193            if [[ $number_of_lines -ne ${expected_lines} ]]; then
194                echo -e "${WARNING_TAG} The output text should have ${expected_lines} lines, but it has ${number_of_lines}."
195                echo -e "${RED} The content is: \n\"\"\""
196                cat ${output_file}_tmp_line
197                echo -e "\"\"\""
198                echo -e "Not adding it to the output file. ${NC}"
199            else
200                if [[ $number_of_lines -gt 1 ]]; then
201                    header_line=$(head -n 1 "${output_file}_tmp_line")
202                    echo -e "${INFO_TAG} Header line is: $header_line"
203                fi
204                result_line=$(tail -n 1 "${output_file}_tmp_line")
205                echo -e "${INFO_TAG} Result line is: $result_line"
206
207                # If this is the first test, we need to add the header line to the output file
208                if [[ $is_first_test -eq 1 ]]; then
209                    append_to_output_file "$header_line" ", command-line" $output_file
210                fi
211
212                command=$(echo $command | sed 's/,/:comma:/g')
213                # Remove the `"` characters from the command line
214                command=$(echo $command | sed 's/\"//g')
215
216                # Append the result line to the output file
217                append_to_output_file "$result_line" ", $command" $output_file
218            fi
219
220            # Always remove the temporary file
221            rm -rf ${output_file}_tmp_line
222
223            # Gather netstat info after running the test
224            if [[ "${get_netstat_info}" == "1" ]]; then
225                echo -e "${INFO_TAG} Getting netstat info after"
226                netstat -s -u | grep -e "error" -e "packet" > $output_folder/${lat_thr}_${role}_${keyed_unkeyed}_${rel_be}${name_suffix}_netstat_after.txt
227                touch "$output_folder/${lat_thr}_${role}_${keyed_unkeyed}_${rel_be}${name_suffix}_netstat.csv"
228                python3 $script_location/../../../tools/diff_netstat_output.py \
229                    -n $output_folder/${lat_thr}_${role}_${keyed_unkeyed}_${rel_be}${name_suffix}_netstat_after.txt \
230                    -o $output_folder/${lat_thr}_${role}_${keyed_unkeyed}_${rel_be}${name_suffix}_netstat_before.txt \
231                    -d $DATALEN $no_header_netstat \
232                    -csv >> "$output_folder/${lat_thr}_${role}_${keyed_unkeyed}_${rel_be}${name_suffix}_netstat.csv"
233                rm -rf $output_folder/${lat_thr}_${role}_${keyed_unkeyed}_${rel_be}${name_suffix}_netstat_*.txt
234                no_header_netstat=" -nh"
235            fi
236
237            change_domain
238        done
239    done
240}
241
242################################################################################
243# PARSE COMMAND LINE OPTIONS:
244
245while [ "$1" != "" ]; do
246    case $1 in
247        --executable)
248            executable=$2
249            shift
250            ;;
251        --docker)
252            DOCKER="1"
253            ;;
254        --output-folder)
255            output_folder=$2
256            shift
257            ;;
258        --role)
259            export role=$2
260            shift
261            ;;
262        --core)
263            export core=$2
264            shift
265            ;;
266        --assign-core-list | --thread-cpu-affinity)
267            export thread_cpu_affinity=$2
268            shift
269            ;;
270        --assign-thread-priorities | --thread-priorities)
271            export thread_priorities=$2
272            shift
273            ;;
274        --pin-memory)
275            export pin_memory="1"
276            ;;
277        --test-kind)
278            export lat_thr=$2
279            shift
280            ;;
281        --interface1)
282            export interface=$2
283            shift
284            ;;
285        --interface2)
286            export interface2=$2
287            shift
288            ;;
289        --ip1)
290            export ip1=$2
291            shift
292            ;;
293        --ip2)
294            export ip2=$2
295            shift
296            ;;
297        --repetitions)
298            export num_reps=$2
299            shift
300            ;;
301        --domain)
302            export domain=$2
303            shift
304            ;;
305        --execution-time)
306            export exec_time=$2
307            shift
308            ;;
309        --transport)
310            export transport=$2
311            shift
312            ;;
313        --datalen)
314            export datalen_input=$2
315            shift
316            ;;
317        --file-suffix)
318            export file_suffix=$2
319            shift
320            ;;
321        --folder-suffix)
322            export folder_suffix=$2
323            shift
324            ;;
325        --sub-folder)
326            sub_folder=$2
327            shift
328            ;;
329        --executable-suffix)
330            export executable_suffix=$2
331            shift
332            ;;
333        --extra-arguments)
334            export extra_arguments=$2
335            shift
336            ;;
337        --extra-arguments-pub)
338            export extra_arguments_pub=$2
339            shift
340            ;;
341        --extra-arguments-sub)
342            export extra_arguments_sub=$2
343            shift
344            ;;
345        --skip-be)
346            export skip_be_tests="1"
347            ;;
348        --skip-rel)
349            export skip_rel_tests="1"
350            ;;
351        --skip-keyed)
352            export skip_keyed_data="1"
353            ;;
354        --skip-large-data)
355            export skip_large_data="1"
356            ;;
357        --large-data)
358            export large_data="1"
359            ;;
360        --keyed)
361            export skip_unkeyed="1"
362            ;;
363        --unkeyed)
364            export skip_keyed_data="1"
365            ;;
366        --no-batching | --skip-batching)
367            export run_batching_tests="0"
368            export run_no_batching_tests="1"
369            ;;
370        --skip-no-batching)
371            export run_batching_tests="1"
372            export run_no_batching_tests="0"
373            ;;
374        --batch-size)
375            export batch_size=$2
376            shift
377            ;;
378        --reliable)
379            export skip_be_tests="1"
380            ;;
381        --best-effort)
382            export skip_rel_tests="1"
383            ;;
384        --security-gov)
385            export security_only="$2"
386            shift
387            ;;
388        --micro)
389            export micro="1"
390            ;;
391        --cert)
392            export cert="1"
393            ;;
394        --raw | --raw-transport)
395            export raw="1"
396            ;;
397        --tss)
398            export tss="1"
399            ;;
400        --no-colors)
401            export NO_COLORS="1"
402            ;;
403        --language)
404            export LANGUAGE=$2
405            shift
406            ;;
407        --loss-rate)
408            export loss_rate=$2
409            shift
410            ;;
411        --get-netstat-info | --netstat)
412            export get_netstat_info="1"
413            ;;
414        --reduced-data-sizes-set)
415            export REDUCED_DATA_SIZES_SET="1"
416            ;;
417        --dont-change-tuned-settings)
418            export dont_change_tuned_settings="1"
419            ;;
420        --no-taskset)
421            export no_taskset=1
422            ;;
423        *)
424            echo -e "unknown parameter \"$1\""
425            exit 255
426            ;;
427    esac
428    shift
429done
430
431if [[ "$NO_COLORS" == "1" ]]; then
432    disable_colors
433fi
434
435export folder_base="$(dirname "${executable}")"/../../..
436
437if [[ $LANGUAGE == "java"  || "$LANGUAGE" == "cs" ]]; then
438    export folder_base="$(dirname "${executable}")"/../..
439fi
440if [[ $tss == "1" ]]; then
441    export folder_base="$(dirname "${executable}")"/../../../../..
442fi
443
444if [[ "${executable_suffix}" != "" ]]; then
445    export executable="${executable}${executable_suffix}"
446fi
447
448if [[ -n "${folder_suffix}" ]]; then
449    export output_folder="${output_folder}${folder_suffix}"
450fi
451
452if [[ -n "${sub_folder}" ]]; then
453    export output_folder="${output_folder}/${sub_folder}"
454fi
455
456echo -e "${INFO_TAG} Perftest executable is: $executable"
457echo -e "${INFO_TAG} Output folder is: $output_folder"
458
459################################################################################
460
461if [[ "$LANGUAGE" == "python" ]]; then
462    export skip_keyed_data="1"
463    export skip_large_data="1"
464    export skip_be_tests="1"
465    export run_no_batching_tests="0"
466fi
467
468if [[ "${skip_large_data}" == "1" ]]; then
469    export datasizes_extended=${datasizes}
470elif [[ "${large_data}" == "1" ]]; then
471    export datasizes=${datasizes_extended}
472fi
473
474if [[ "${datalen_input}" != "" ]]; then
475    echo -e "${YELLOW}[TEST] Testing only for ${datalen_input}${NC}"
476    export datasizes=${datalen_input}
477    export datasizes_extended=${datalen_input}
478    if [[ "${run_no_batching_tests}" == "1" && "${run_batching_tests}" == "0" ]]; then
479        export skip_large_data="1"
480    fi
481else 
482    if [[ "${REDUCED_DATA_SIZES_SET}" != "" ]]; then
483        echo -e "${YELLOW}[TEST] Testing Reduced set of datasizes ${NC}"
484        export datasizes="32 128 512 2048 8192 32768 63000"
485        export datasizes_extended="${datasizes} 102400 1048576 10485760"
486    fi
487fi
488
489if [[ "$role" != "pub" && "$role" != "sub" ]]; then
490    echo -e "${ERROR_TAG} It must be either publisher or subscriber"
491    exit 255
492fi
493
494if [[ "$lat_thr" != "thr" && "$lat_thr" != "lat" ]]; then
495    echo -e "${ERROR_TAG} It must be either lat or thr"
496    exit 255
497fi
498
499if [[ "${interface}" == "" ]]; then
500    echo "Using default nics"
501    export nic_publisher=${ip_machine_1}
502    export nic_subscriber=${ip_machine_2}
503elif [[ "${interface}" == "both" ]]; then
504    export nic_publisher="enp1s0f0,eno1"
505    export nic_subscriber="enp1s0f0,eno1"
506    echo -e "${INFO_TAG} Using nic_publisher: ${nic_publisher}"
507    echo -e "${INFO_TAG} Using nic_subscriber: ${nic_subscriber}"
508else
509    export nic_publisher=$interface
510    echo -e "${INFO_TAG} Using nic_publisher: ${nic_publisher}"
511
512    if [[ "${interface2}" == "" ]]; then
513        export nic_subscriber=$interface
514    else
515        export nic_subscriber=$interface2
516    fi
517    echo -e "${INFO_TAG} Using nic_subscriber: ${nic_subscriber}"
518
519    if [[ "${ip1}" != "" ]]; then
520        export ip_publisher=$ip1
521        echo "Using ip_publisher: ${ip_publisher}"
522    fi
523
524    if [[ "${ip2}" != "" ]]; then
525        export ip_subscriber=$ip2
526        echo "Using ip_subscriber: ${ip_subscriber}"
527    fi
528
529fi
530
531export transport_string="-transport $transport"
532
533if [[ "$transport" == "UDPv4" ]]; then
534
535    export transport_string_pub="$transport_string -nic $nic_publisher"
536    export transport_string_sub="$transport_string -nic $nic_subscriber"
537
538    if [[ "$raw" == "1" ]]; then
539        export transport_string_pub="$transport_string_pub -peer ${ip_subscriber}"
540        export transport_string_sub="$transport_string_sub -peer ${ip_publisher}"
541    fi
542
543    if [[ "$micro" == "1" || "$cert" == "1" ]]; then
544        export transport_string_pub="$transport_string_pub -peer _udp://${ip_subscriber}"
545        export transport_string_sub="$transport_string_sub -peer _udp://${ip_publisher}"
546    fi
547
548elif [[ "$transport" == "TCP" ]]; then
549    export transport_string_pub="$transport_string \
550        -nic $nic_publisher \
551        -peer 0@tcpv4_lan://${ip_subscriber}:7400"
552    export transport_string_sub="$transport_string \
553        -nic $nic_subscriber \
554        -peer 0@tcpv4_lan://${ip_publisher}:7400"
555elif [[ "$transport" == "TLS" ]]; then
556    export transport_string_pub="$transport_string \
557        -nic $nic_publisher \
558        -peer tlsv4_lan://${ip_subscriber}:7400"
559    export transport_string_sub="$transport_string \
560        -nic $nic_subscriber \
561        -peer tlsv4_lan://${ip_publisher}:7400"
562elif [[ "$transport" == "UDPv4_WAN" ]]; then
563    export transport_string_pub="$transport_string \
564        -nic $nic_publisher \
565        -transportPublicAddress $ip_publisher:7400"
566    export transport_string_sub="$transport_string \
567        -nic $nic_subscriber \
568        -peer 0@udpv4_wan://${ip_publisher}:7400"
569else
570    export transport_string_pub="$transport_string"
571    export transport_string_sub="$transport_string"
572fi
573
574################################################################################
575
576export pub_string="-pub \
577        ${transport_string_pub} \
578        -noPrintIntervals \
579        -executionTime $exec_time"
580
581if [[ ${lat_thr} == "lat" ]]; then
582    export pub_string="$pub_string \
583        -latencyTest"
584fi
585
586export sub_string="-sub \
587        ${transport_string_sub} \
588        -noPrintIntervals"
589
590if [[ "$role" == "pub" ]]; then
591    echo -e "$INFO_TAG Publisher side running"
592    export commands_string=${pub_string}
593    export extra_arguments="${extra_arguments} ${extra_arguments_pub}"
594else
595    echo -e "$INFO_TAG Subscriber side running"
596    export commands_string=${sub_string}
597    export extra_arguments="${extra_arguments} ${extra_arguments_sub}"
598fi
599
600###############################################################################
601
602if [[ "$dont_change_tuned_settings" != "1" ]]; then
603    echo -e "${INFO_TAG} Executing: /set_${lat_thr}_mode.sh"
604    sudo /set_${lat_thr}_mode.sh
605    sleep 5
606fi
607
608echo -e "${INFO_TAG} Disabling any loss rate"
609sudo tc qdisc add dev $nic_publisher root netem loss 0%
610sudo tc qdisc del dev $nic_publisher root netem loss 0%
611
612if [[ "$role" == "pub" && "${loss_rate}" != "" ]]; then
613    echo -e "${INFO_TAG} Setting loss rate to ${loss_rate}%"
614    sudo tc qdisc add dev $nic_publisher root netem loss $loss_rate%
615fi
616
617cd $folder_base
618echo -e "${INFO_TAG} Folder Base is: $PWD"
619mkdir -p $output_folder
620
621if [[ "${batch_size}" != "" ]]; then
622    if [[ "${lat_thr}" == "thr" ]]; then
623        if [[ "${batch_size}" -eq 0 ]]; then
624            echo -e "${INFO_TAG} Batch size is set to 0"
625            export run_batching_tests="0"
626            export run_no_batching_tests="1"
627        else
628            echo -e "${INFO_TAG} Batch size is set to ${batch_size}"
629            export run_batching_tests="1"
630            export run_no_batching_tests="0"
631        fi
632    else
633        echo -e "${INFO_TAG} Batch size is set to ${batch_size}. This value will be ignored for latency tests."
634        unset batch_size
635    fi
636fi
637
638# Tests that may use batching (when doing throughput tests). Also Latency tests.
639if [[ ${run_batching_tests} == "1" ]]; then
640
641    # UNKEYED
642    if [[ "${skip_unkeyed}" == "" ]]; then
643
644        # RELIABLE
645        if [[ "${skip_rel_tests}" == "" ]]; then
646            execute_test "unkeyed" "rel" "${datasizes_extended}" "${extra_arguments}" "$file_suffix"
647        fi
648
649        # BEST EFFORT
650        if [[ "${skip_be_tests}" == "" ]]; then
651            execute_test "unkeyed" "be" "${datasizes}" "${extra_arguments}" "$file_suffix"
652        fi
653    fi
654
655    # KEYED
656    if [[ "${skip_keyed_data}" == "" ]]; then
657
658        # RELIABLE
659        if [[ "${skip_rel_tests}" == "" ]]; then
660            execute_test "keyed" "rel" "${datasizes}" "${extra_arguments}" "$file_suffix"
661        fi
662
663        # BEST EFFORT
664        if [[ "${skip_be_tests}" == "" ]]; then
665            execute_test "keyed" "be" "${datasizes}" "${extra_arguments}" "$file_suffix"
666        fi
667    fi
668
669fi
670
671# Tests that will not use batching
672if [[ "${lat_thr}" == "thr" && "${run_no_batching_tests}" == "1" ]]; then
673
674    if [[ "$role" == "pub" ]]; then
675        export commands_string="${commands_string} -batchSize 0"
676    fi
677
678    # UNKEYED
679    if [[ "${skip_unkeyed}" == "" ]]; then
680
681        # RELIABLE
682        if [[ "${skip_rel_tests}" == "" ]]; then
683            execute_test "unkeyed" "rel" "${datasizes}" "${extra_arguments}" "_noBatch${file_suffix}"
684        fi
685
686        # BEST EFFORT
687        if [[ "${skip_be_tests}" == "" ]]; then
688            execute_test "unkeyed" "be" "${datasizes}" "${extra_arguments}" "_noBatch${file_suffix}"
689        fi
690    fi
691
692    # KEYED
693    if [[ "${skip_keyed_data}" == "" ]]; then
694
695        # RELIABLE
696        if [[ "${skip_rel_tests}" == "" ]]; then
697            execute_test "keyed" "rel" "${datasizes}" "${extra_arguments}" "_noBatch${file_suffix}"
698        fi
699
700        # BEST EFFORT
701        if [[ "${skip_be_tests}" == "" ]]; then
702            execute_test "keyed" "be" "${datasizes}" "${extra_arguments}" "_noBatch${file_suffix}"
703        fi
704    fi
705
706fi
707
708if [[ "$role" == "pub" && "${loss_rate}" != "" ]]; then
709    echo -e "${INFO_TAG} Disabling loss rate"
710    sudo tc qdisc del dev $nic_publisher root netem loss $loss_rate%
711fi
1#!/bin/bash
2filename=$0
3script_location=$(cd "$(dirname "$filename")" || exit 255; pwd)
4
5echo -e "[Calling base_script/script.sh]"
6"${script_location}/../base_script/script.sh" $@ --transport UDPv4

Test Software

The following software was used to perform these tests:

RTI Connext DDS 6.1.1 Host and Target Libraries for x64 Linux (x64Linux4gcc7.3.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 20.04 -- gcc 9.3.0

Switch

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

Keyed, UDPv4 10Gbps Network, C++98

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.

  • Best Effort

Sample Size (Bytes)

Ave (μs)

Std (μs)

Min (μs)

Max (μs)

50% (μs)

90% (μs)

99% (μs)

99.99% (μs)

99.9999% (μs)

32

17

1.0

17

167

17

18

20

47

167

64

17

1.2

17

170

17

18

21

46

170

128

18

1.1

17

167

18

19

21

48

167

256

18

1.1

17

165

18

19

21

48

165

512

19

1.2

17

175

19

20

22

49

175

1024

25

3.5

19

175

26

28

29

56

175

2048

32

171.7

21

100070

30

61

64

79

100070

4096

33

158.2

26

100062

30

44

58

70

100062

8192

46

214.6

35

100070

41

60

64

85

100070

16384

93

25.2

48

276

82

126

131

151

276

32768

176

2.5

70

321

176

177

179

206

321

63000

188

2.8

105

331

188

189

191

217

331

  • Reliable

Sample Size (Bytes)

Ave (μs)

Std (μs)

Min (μs)

Max (μs)

50% (μs)

90% (μs)

99% (μs)

99.99% (μs)

99.9999% (μs)

32

19

1.2

18

166

19

20

23

49

166

64

20

1.3

18

166

19

20

24

50

166

128

19

1.3

18

167

19

20

25

49

167

256

20

5.0

18

3169

19

21

27

50

3169

512

21

2.3

19

171

20

22

29

51

171

1024

26

8.5

20

3437

26

28

46

58

3437

2048

29

14.5

22

4215

30

32

43

66

4215

4096

31

18.9

27

5027

30

33

51

66

5027

8192

44

48.3

37

4854

39

55

73

3352

4854

16384

93

24.9

48

270

86

126

132

152

270

32768

162

15.8

78

244

167

177

180

205

244

63000

189

2.7

108

260

188

190

194

219

260


Perftest Scripts

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

  1#!/bin/bash
  2filename=$0
  3script_location=$(cd "$(dirname "$filename")" || exit 255; pwd)
  4
  5export datasizes="32 64 128 256 512 1024 2048 4096 8192 16384 32768 63000"
  6export datasizes_extended="${datasizes} 100000 500000 1048576 1548576 4194304 10485760"
  7
  8export domain="2"
  9export exec_time=20
 10export num_reps=1
 11export instance_number=100000
 12export core=0
 13export run_batching_tests="1"
 14export run_no_batching_tests="1"
 15
 16# We will use some colors to improve visibility of errors and info messages.
 17RED='\033[0;31m'
 18GREEN='\033[0;32m'
 19YELLOW='\033[0;33m'
 20BLUE='\033[0;34m'
 21LIGHTBLUE='\033[0;36m'
 22NC='\033[0m'
 23INFO_TAG="${GREEN}[INFO][$role]:${NC}"
 24WARNING_TAG="${YELLOW}[WARNING][$role]:${NC}"
 25ERROR_TAG="${RED}[ERROR][$role]:${NC}"
 26
 27################################################################################
 28
 29function disable_colors() {
 30    export RED=""
 31    export GREEN=""
 32    export YELLOW=""
 33    export NC=""
 34    export BLUE=""
 35    export LIGHTBLUE=""
 36    export INFO_TAG="${GREEN}[INFO][$role]:${NC}"
 37    export WARNING_TAG="${YELLOW}[WARNING][$role]:${NC}"
 38    export ERROR_TAG="${RED}[ERROR][$role]:${NC}"
 39}
 40
 41function change_domain() {
 42    if [[ "$domain" == "1" ]]; then
 43        export domain="2"
 44    else
 45        export domain="1"
 46    fi
 47}
 48
 49# Function to process and append lines to the output file
 50function append_to_output_file() {
 51    local line=${1?line required}; readonly line
 52    local append=$(echo "${2?append required}" | tr -s ' '); readonly append
 53    local file=${3?file required}; readonly file
 54    if [[ "${line: -1}" == $'\n' ]]; then
 55        line="${line::-1}"
 56    fi
 57    echo "${line}${append}" >> "$file"
 58}
 59
 60# Usage: execute_test <keyed/unkeyed> <rel/be> <datasizes> <batchSize>
 61function execute_test() {
 62
 63    local keyed_unkeyed=$1
 64    local rel_be=$2
 65    local datasizes_test=$3
 66    local other_args=$4
 67    local name_suffix=$5
 68
 69    local commands_string_test=$commands_string
 70    local tag=""
 71
 72    if [[ "${keyed_unkeyed}" == "keyed" ]]; then
 73        commands_string_test="${commands_string_test} -keyed -instances $instance_number"
 74        tag="[${YELLOW}${transport}${NC}|${BLUE}K${NC}|"
 75    else
 76        tag="[${YELLOW}${transport}${NC}|${LIGHTBLUE}UK${NC}|"
 77    fi
 78
 79    if [[ "${rel_be}" == "be" ]]; then
 80        commands_string_test="${commands_string_test} -bestEffort"
 81        tag="${tag}${YELLOW}BE${NC}]"
 82    else
 83        tag="${tag}${RED}REL${NC}]"
 84    fi
 85
 86    # If batch_size is set, we will add it to the command line of the publisher side.
 87    if [[ "$batch_size" != "" && "$role" == "pub" ]]; then
 88        commands_string_test="${commands_string_test} -batchSize $batch_size"
 89    fi
 90
 91    tag="${tag}[${LIGHTBLUE}${lat_thr}${NC}]"
 92
 93    local output_file=$output_folder/${lat_thr}_${role}_${keyed_unkeyed}_${rel_be}${name_suffix}.csv
 94
 95    if [[ "$role" == "pub" ]]; then
 96        echo -e "${YELLOW}[TEST]: $keyed_unkeyed, $rel_be, Is a no-batching test = $no_batching_tests. ${NC}"
 97    fi
 98
 99    if [[ "$thread_cpu_affinity" != "" ]]; then
100        commands_string_test="${commands_string_test} -threadCPUAffinity $thread_cpu_affinity"
101    fi
102
103    local pre_command_string=""
104
105    if [[ "$thread_priorities" != "" ]]; then
106        echo -e "${WARNING_TAG} Thread priorities enabled, this requires using sudo"
107        # When using sudo, the LD_LIBRARY_PATH is emptied, hence we need to set it again in the command itself
108        export LD_LIBRARY_PATH_COPIED="$LD_LIBRARY_PATH"
109        pre_command_string="sudo LD_LIBRARY_PATH=$LD_LIBRARY_PATH_COPIED "
110        commands_string_test="${commands_string_test} -threadPriorities $thread_priorities"
111    fi
112
113    if [[ "$pin_memory" != "" ]]; then
114        commands_string_test="${commands_string_test} -pinMemory"
115    fi
116
117    if [[ "$no_taskset" == "" && "$thread_cpu_affinity" == "" && "$LANGUAGE" != "java" && "$LANGUAGE" != "cs" ]]; then
118        pre_command_string="$pre_command_string taskset -c $core"
119    fi
120
121    if [[ "$LANGUAGE" == "python" ]]; then
122        pre_command_string="$pre_command_string python3 "
123    fi
124
125    if [[ "$DOCKER" == "1" ]]; then
126        pre_command_string="$pre_command_string docker run --net=host -v /home/perfuser/rti_license_connextpro.dat:/opt/rti.com/rti_connext_dds-7.3.0/rti_license.dat rticom/perftest:7.3.0-EAR "
127        executable=""
128    fi
129
130    # Get the aprox time this will take:
131    total_tests=$((`wc -w <<< "$datasizes_test"` * num_reps))
132    total_time=$((total_tests * exec_time))
133
134    touch $output_file
135    local no_headers=""
136    local current_test=0
137    for index in $(seq 1 ${num_reps}); do
138        for DATALEN in ${datasizes_test}; do
139            current_test=$((current_test + 1))
140
141            if [[ ! -s $output_file ]]; then
142                echo -e "${INFO_TAG} Output file is empty, filling the header."
143                no_headers=""
144            else
145                echo -e "${INFO_TAG} Output file is not empty."
146                no_headers=" -noOutputHeaders"
147            fi
148
149            export command="$pre_command_string $executable -domain $domain -dataLen $DATALEN $commands_string_test $other_args $no_headers"
150            if [[ "$role" == "pub" ]]; then
151                echo -e "Test ${tag} (${current_test}/${total_tests}) -- Total time = ${total_time}s"
152                echo -e ${BLUE}$command${NC}
153            else
154                echo -e ${LIGHTBLUE}$command${NC}
155            fi
156
157            # In certain cases we need to wait a bit before running the test, this is
158            # because the previous test might not be finished on the other side yet, or because the
159            # discovery mechanism does not work like in connext DDS.
160            if [[ "$LANGUAGE" == "cs" && "$role" == "pub" ]]; then
161                sleep 3
162            fi
163            if [[ "$raw" == "1" && "$role" == "sub" ]]; then
164                sleep 5
165            fi
166
167            # Gather netstat info before running the test
168            if [[ "${get_netstat_info}" == "1" ]]; then
169                echo -e "${INFO_TAG} Getting netstat info before"
170                netstat -s -u | grep -e "error" -e "packet" > $output_folder/${lat_thr}_${role}_${keyed_unkeyed}_${rel_be}${name_suffix}_netstat_before.txt
171            fi
172
173            # Execute the command and capture the output
174            if [[ $LANGUAGE == "c++98" || $LANGUAGE == "" ]]; then
175                echo -e "${INFO_TAG} Using C++98, using -outputFile option"
176                touch ${output_file}_tmp_line
177                chmod 777 ${output_file}_tmp_line
178                eval $command -outputFile ${output_file}_tmp_line
179            else
180                eval $command > ${output_file}_tmp_line
181            fi
182
183            number_of_lines=$(wc -l < ${output_file}_tmp_line)
184            echo -e "${INFO_TAG} Size of the output text: $number_of_lines lines"
185
186            # Check if this is the first test for this output file.
187            local is_first_test=0
188            if [[ ! -s $output_file ]]; then
189                is_first_test=1
190            fi
191            local expected_lines=$((is_first_test+1))
192
193            if [[ $number_of_lines -ne ${expected_lines} ]]; then
194                echo -e "${WARNING_TAG} The output text should have ${expected_lines} lines, but it has ${number_of_lines}."
195                echo -e "${RED} The content is: \n\"\"\""
196                cat ${output_file}_tmp_line
197                echo -e "\"\"\""
198                echo -e "Not adding it to the output file. ${NC}"
199            else
200                if [[ $number_of_lines -gt 1 ]]; then
201                    header_line=$(head -n 1 "${output_file}_tmp_line")
202                    echo -e "${INFO_TAG} Header line is: $header_line"
203                fi
204                result_line=$(tail -n 1 "${output_file}_tmp_line")
205                echo -e "${INFO_TAG} Result line is: $result_line"
206
207                # If this is the first test, we need to add the header line to the output file
208                if [[ $is_first_test -eq 1 ]]; then
209                    append_to_output_file "$header_line" ", command-line" $output_file
210                fi
211
212                command=$(echo $command | sed 's/,/:comma:/g')
213                # Remove the `"` characters from the command line
214                command=$(echo $command | sed 's/\"//g')
215
216                # Append the result line to the output file
217                append_to_output_file "$result_line" ", $command" $output_file
218            fi
219
220            # Always remove the temporary file
221            rm -rf ${output_file}_tmp_line
222
223            # Gather netstat info after running the test
224            if [[ "${get_netstat_info}" == "1" ]]; then
225                echo -e "${INFO_TAG} Getting netstat info after"
226                netstat -s -u | grep -e "error" -e "packet" > $output_folder/${lat_thr}_${role}_${keyed_unkeyed}_${rel_be}${name_suffix}_netstat_after.txt
227                touch "$output_folder/${lat_thr}_${role}_${keyed_unkeyed}_${rel_be}${name_suffix}_netstat.csv"
228                python3 $script_location/../../../tools/diff_netstat_output.py \
229                    -n $output_folder/${lat_thr}_${role}_${keyed_unkeyed}_${rel_be}${name_suffix}_netstat_after.txt \
230                    -o $output_folder/${lat_thr}_${role}_${keyed_unkeyed}_${rel_be}${name_suffix}_netstat_before.txt \
231                    -d $DATALEN $no_header_netstat \
232                    -csv >> "$output_folder/${lat_thr}_${role}_${keyed_unkeyed}_${rel_be}${name_suffix}_netstat.csv"
233                rm -rf $output_folder/${lat_thr}_${role}_${keyed_unkeyed}_${rel_be}${name_suffix}_netstat_*.txt
234                no_header_netstat=" -nh"
235            fi
236
237            change_domain
238        done
239    done
240}
241
242################################################################################
243# PARSE COMMAND LINE OPTIONS:
244
245while [ "$1" != "" ]; do
246    case $1 in
247        --executable)
248            executable=$2
249            shift
250            ;;
251        --docker)
252            DOCKER="1"
253            ;;
254        --output-folder)
255            output_folder=$2
256            shift
257            ;;
258        --role)
259            export role=$2
260            shift
261            ;;
262        --core)
263            export core=$2
264            shift
265            ;;
266        --assign-core-list | --thread-cpu-affinity)
267            export thread_cpu_affinity=$2
268            shift
269            ;;
270        --assign-thread-priorities | --thread-priorities)
271            export thread_priorities=$2
272            shift
273            ;;
274        --pin-memory)
275            export pin_memory="1"
276            ;;
277        --test-kind)
278            export lat_thr=$2
279            shift
280            ;;
281        --interface1)
282            export interface=$2
283            shift
284            ;;
285        --interface2)
286            export interface2=$2
287            shift
288            ;;
289        --ip1)
290            export ip1=$2
291            shift
292            ;;
293        --ip2)
294            export ip2=$2
295            shift
296            ;;
297        --repetitions)
298            export num_reps=$2
299            shift
300            ;;
301        --domain)
302            export domain=$2
303            shift
304            ;;
305        --execution-time)
306            export exec_time=$2
307            shift
308            ;;
309        --transport)
310            export transport=$2
311            shift
312            ;;
313        --datalen)
314            export datalen_input=$2
315            shift
316            ;;
317        --file-suffix)
318            export file_suffix=$2
319            shift
320            ;;
321        --folder-suffix)
322            export folder_suffix=$2
323            shift
324            ;;
325        --sub-folder)
326            sub_folder=$2
327            shift
328            ;;
329        --executable-suffix)
330            export executable_suffix=$2
331            shift
332            ;;
333        --extra-arguments)
334            export extra_arguments=$2
335            shift
336            ;;
337        --extra-arguments-pub)
338            export extra_arguments_pub=$2
339            shift
340            ;;
341        --extra-arguments-sub)
342            export extra_arguments_sub=$2
343            shift
344            ;;
345        --skip-be)
346            export skip_be_tests="1"
347            ;;
348        --skip-rel)
349            export skip_rel_tests="1"
350            ;;
351        --skip-keyed)
352            export skip_keyed_data="1"
353            ;;
354        --skip-large-data)
355            export skip_large_data="1"
356            ;;
357        --large-data)
358            export large_data="1"
359            ;;
360        --keyed)
361            export skip_unkeyed="1"
362            ;;
363        --unkeyed)
364            export skip_keyed_data="1"
365            ;;
366        --no-batching | --skip-batching)
367            export run_batching_tests="0"
368            export run_no_batching_tests="1"
369            ;;
370        --skip-no-batching)
371            export run_batching_tests="1"
372            export run_no_batching_tests="0"
373            ;;
374        --batch-size)
375            export batch_size=$2
376            shift
377            ;;
378        --reliable)
379            export skip_be_tests="1"
380            ;;
381        --best-effort)
382            export skip_rel_tests="1"
383            ;;
384        --security-gov)
385            export security_only="$2"
386            shift
387            ;;
388        --micro)
389            export micro="1"
390            ;;
391        --cert)
392            export cert="1"
393            ;;
394        --raw | --raw-transport)
395            export raw="1"
396            ;;
397        --tss)
398            export tss="1"
399            ;;
400        --no-colors)
401            export NO_COLORS="1"
402            ;;
403        --language)
404            export LANGUAGE=$2
405            shift
406            ;;
407        --loss-rate)
408            export loss_rate=$2
409            shift
410            ;;
411        --get-netstat-info | --netstat)
412            export get_netstat_info="1"
413            ;;
414        --reduced-data-sizes-set)
415            export REDUCED_DATA_SIZES_SET="1"
416            ;;
417        --dont-change-tuned-settings)
418            export dont_change_tuned_settings="1"
419            ;;
420        --no-taskset)
421            export no_taskset=1
422            ;;
423        *)
424            echo -e "unknown parameter \"$1\""
425            exit 255
426            ;;
427    esac
428    shift
429done
430
431if [[ "$NO_COLORS" == "1" ]]; then
432    disable_colors
433fi
434
435export folder_base="$(dirname "${executable}")"/../../..
436
437if [[ $LANGUAGE == "java"  || "$LANGUAGE" == "cs" ]]; then
438    export folder_base="$(dirname "${executable}")"/../..
439fi
440if [[ $tss == "1" ]]; then
441    export folder_base="$(dirname "${executable}")"/../../../../..
442fi
443
444if [[ "${executable_suffix}" != "" ]]; then
445    export executable="${executable}${executable_suffix}"
446fi
447
448if [[ -n "${folder_suffix}" ]]; then
449    export output_folder="${output_folder}${folder_suffix}"
450fi
451
452if [[ -n "${sub_folder}" ]]; then
453    export output_folder="${output_folder}/${sub_folder}"
454fi
455
456echo -e "${INFO_TAG} Perftest executable is: $executable"
457echo -e "${INFO_TAG} Output folder is: $output_folder"
458
459################################################################################
460
461if [[ "$LANGUAGE" == "python" ]]; then
462    export skip_keyed_data="1"
463    export skip_large_data="1"
464    export skip_be_tests="1"
465    export run_no_batching_tests="0"
466fi
467
468if [[ "${skip_large_data}" == "1" ]]; then
469    export datasizes_extended=${datasizes}
470elif [[ "${large_data}" == "1" ]]; then
471    export datasizes=${datasizes_extended}
472fi
473
474if [[ "${datalen_input}" != "" ]]; then
475    echo -e "${YELLOW}[TEST] Testing only for ${datalen_input}${NC}"
476    export datasizes=${datalen_input}
477    export datasizes_extended=${datalen_input}
478    if [[ "${run_no_batching_tests}" == "1" && "${run_batching_tests}" == "0" ]]; then
479        export skip_large_data="1"
480    fi
481else 
482    if [[ "${REDUCED_DATA_SIZES_SET}" != "" ]]; then
483        echo -e "${YELLOW}[TEST] Testing Reduced set of datasizes ${NC}"
484        export datasizes="32 128 512 2048 8192 32768 63000"
485        export datasizes_extended="${datasizes} 102400 1048576 10485760"
486    fi
487fi
488
489if [[ "$role" != "pub" && "$role" != "sub" ]]; then
490    echo -e "${ERROR_TAG} It must be either publisher or subscriber"
491    exit 255
492fi
493
494if [[ "$lat_thr" != "thr" && "$lat_thr" != "lat" ]]; then
495    echo -e "${ERROR_TAG} It must be either lat or thr"
496    exit 255
497fi
498
499if [[ "${interface}" == "" ]]; then
500    echo "Using default nics"
501    export nic_publisher=${ip_machine_1}
502    export nic_subscriber=${ip_machine_2}
503elif [[ "${interface}" == "both" ]]; then
504    export nic_publisher="enp1s0f0,eno1"
505    export nic_subscriber="enp1s0f0,eno1"
506    echo -e "${INFO_TAG} Using nic_publisher: ${nic_publisher}"
507    echo -e "${INFO_TAG} Using nic_subscriber: ${nic_subscriber}"
508else
509    export nic_publisher=$interface
510    echo -e "${INFO_TAG} Using nic_publisher: ${nic_publisher}"
511
512    if [[ "${interface2}" == "" ]]; then
513        export nic_subscriber=$interface
514    else
515        export nic_subscriber=$interface2
516    fi
517    echo -e "${INFO_TAG} Using nic_subscriber: ${nic_subscriber}"
518
519    if [[ "${ip1}" != "" ]]; then
520        export ip_publisher=$ip1
521        echo "Using ip_publisher: ${ip_publisher}"
522    fi
523
524    if [[ "${ip2}" != "" ]]; then
525        export ip_subscriber=$ip2
526        echo "Using ip_subscriber: ${ip_subscriber}"
527    fi
528
529fi
530
531export transport_string="-transport $transport"
532
533if [[ "$transport" == "UDPv4" ]]; then
534
535    export transport_string_pub="$transport_string -nic $nic_publisher"
536    export transport_string_sub="$transport_string -nic $nic_subscriber"
537
538    if [[ "$raw" == "1" ]]; then
539        export transport_string_pub="$transport_string_pub -peer ${ip_subscriber}"
540        export transport_string_sub="$transport_string_sub -peer ${ip_publisher}"
541    fi
542
543    if [[ "$micro" == "1" || "$cert" == "1" ]]; then
544        export transport_string_pub="$transport_string_pub -peer _udp://${ip_subscriber}"
545        export transport_string_sub="$transport_string_sub -peer _udp://${ip_publisher}"
546    fi
547
548elif [[ "$transport" == "TCP" ]]; then
549    export transport_string_pub="$transport_string \
550        -nic $nic_publisher \
551        -peer 0@tcpv4_lan://${ip_subscriber}:7400"
552    export transport_string_sub="$transport_string \
553        -nic $nic_subscriber \
554        -peer 0@tcpv4_lan://${ip_publisher}:7400"
555elif [[ "$transport" == "TLS" ]]; then
556    export transport_string_pub="$transport_string \
557        -nic $nic_publisher \
558        -peer tlsv4_lan://${ip_subscriber}:7400"
559    export transport_string_sub="$transport_string \
560        -nic $nic_subscriber \
561        -peer tlsv4_lan://${ip_publisher}:7400"
562elif [[ "$transport" == "UDPv4_WAN" ]]; then
563    export transport_string_pub="$transport_string \
564        -nic $nic_publisher \
565        -transportPublicAddress $ip_publisher:7400"
566    export transport_string_sub="$transport_string \
567        -nic $nic_subscriber \
568        -peer 0@udpv4_wan://${ip_publisher}:7400"
569else
570    export transport_string_pub="$transport_string"
571    export transport_string_sub="$transport_string"
572fi
573
574################################################################################
575
576export pub_string="-pub \
577        ${transport_string_pub} \
578        -noPrintIntervals \
579        -executionTime $exec_time"
580
581if [[ ${lat_thr} == "lat" ]]; then
582    export pub_string="$pub_string \
583        -latencyTest"
584fi
585
586export sub_string="-sub \
587        ${transport_string_sub} \
588        -noPrintIntervals"
589
590if [[ "$role" == "pub" ]]; then
591    echo -e "$INFO_TAG Publisher side running"
592    export commands_string=${pub_string}
593    export extra_arguments="${extra_arguments} ${extra_arguments_pub}"
594else
595    echo -e "$INFO_TAG Subscriber side running"
596    export commands_string=${sub_string}
597    export extra_arguments="${extra_arguments} ${extra_arguments_sub}"
598fi
599
600###############################################################################
601
602if [[ "$dont_change_tuned_settings" != "1" ]]; then
603    echo -e "${INFO_TAG} Executing: /set_${lat_thr}_mode.sh"
604    sudo /set_${lat_thr}_mode.sh
605    sleep 5
606fi
607
608echo -e "${INFO_TAG} Disabling any loss rate"
609sudo tc qdisc add dev $nic_publisher root netem loss 0%
610sudo tc qdisc del dev $nic_publisher root netem loss 0%
611
612if [[ "$role" == "pub" && "${loss_rate}" != "" ]]; then
613    echo -e "${INFO_TAG} Setting loss rate to ${loss_rate}%"
614    sudo tc qdisc add dev $nic_publisher root netem loss $loss_rate%
615fi
616
617cd $folder_base
618echo -e "${INFO_TAG} Folder Base is: $PWD"
619mkdir -p $output_folder
620
621if [[ "${batch_size}" != "" ]]; then
622    if [[ "${lat_thr}" == "thr" ]]; then
623        if [[ "${batch_size}" -eq 0 ]]; then
624            echo -e "${INFO_TAG} Batch size is set to 0"
625            export run_batching_tests="0"
626            export run_no_batching_tests="1"
627        else
628            echo -e "${INFO_TAG} Batch size is set to ${batch_size}"
629            export run_batching_tests="1"
630            export run_no_batching_tests="0"
631        fi
632    else
633        echo -e "${INFO_TAG} Batch size is set to ${batch_size}. This value will be ignored for latency tests."
634        unset batch_size
635    fi
636fi
637
638# Tests that may use batching (when doing throughput tests). Also Latency tests.
639if [[ ${run_batching_tests} == "1" ]]; then
640
641    # UNKEYED
642    if [[ "${skip_unkeyed}" == "" ]]; then
643
644        # RELIABLE
645        if [[ "${skip_rel_tests}" == "" ]]; then
646            execute_test "unkeyed" "rel" "${datasizes_extended}" "${extra_arguments}" "$file_suffix"
647        fi
648
649        # BEST EFFORT
650        if [[ "${skip_be_tests}" == "" ]]; then
651            execute_test "unkeyed" "be" "${datasizes}" "${extra_arguments}" "$file_suffix"
652        fi
653    fi
654
655    # KEYED
656    if [[ "${skip_keyed_data}" == "" ]]; then
657
658        # RELIABLE
659        if [[ "${skip_rel_tests}" == "" ]]; then
660            execute_test "keyed" "rel" "${datasizes}" "${extra_arguments}" "$file_suffix"
661        fi
662
663        # BEST EFFORT
664        if [[ "${skip_be_tests}" == "" ]]; then
665            execute_test "keyed" "be" "${datasizes}" "${extra_arguments}" "$file_suffix"
666        fi
667    fi
668
669fi
670
671# Tests that will not use batching
672if [[ "${lat_thr}" == "thr" && "${run_no_batching_tests}" == "1" ]]; then
673
674    if [[ "$role" == "pub" ]]; then
675        export commands_string="${commands_string} -batchSize 0"
676    fi
677
678    # UNKEYED
679    if [[ "${skip_unkeyed}" == "" ]]; then
680
681        # RELIABLE
682        if [[ "${skip_rel_tests}" == "" ]]; then
683            execute_test "unkeyed" "rel" "${datasizes}" "${extra_arguments}" "_noBatch${file_suffix}"
684        fi
685
686        # BEST EFFORT
687        if [[ "${skip_be_tests}" == "" ]]; then
688            execute_test "unkeyed" "be" "${datasizes}" "${extra_arguments}" "_noBatch${file_suffix}"
689        fi
690    fi
691
692    # KEYED
693    if [[ "${skip_keyed_data}" == "" ]]; then
694
695        # RELIABLE
696        if [[ "${skip_rel_tests}" == "" ]]; then
697            execute_test "keyed" "rel" "${datasizes}" "${extra_arguments}" "_noBatch${file_suffix}"
698        fi
699
700        # BEST EFFORT
701        if [[ "${skip_be_tests}" == "" ]]; then
702            execute_test "keyed" "be" "${datasizes}" "${extra_arguments}" "_noBatch${file_suffix}"
703        fi
704    fi
705
706fi
707
708if [[ "$role" == "pub" && "${loss_rate}" != "" ]]; then
709    echo -e "${INFO_TAG} Disabling loss rate"
710    sudo tc qdisc del dev $nic_publisher root netem loss $loss_rate%
711fi
1#!/bin/bash
2filename=$0
3script_location=$(cd "$(dirname "$filename")" || exit 255; pwd)
4
5echo -e "[Calling base_script/script.sh]"
6"${script_location}/../base_script/script.sh" $@ --transport UDPv4

Test Software

The following software was used to perform these tests:

RTI Connext DDS 6.1.2 Host and Target Libraries for x64 Linux (x64Linux4gcc7.3.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 20.04 -- gcc 9.3.0

Switch

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