@@ -77,6 +77,12 @@ mutilate (EuroSys \'14) [https://github.com/leverich/mutilate]
7777 appending '--threads=T --connections=4' to the driver command during load
7878 tests. T will be the lesser of requested_qps / 4 or $( nproc) / 5.
7979 -o output filename to record samples as csv. Optional
80+ -r QPS increase threshold for steady state detection during warmup (in percentage).
81+ When specified, warmup continues until QPS increase is less than this threshold
82+ percentage of the previous QPS. Optional
83+ -x Maximum number of warmup iterations when using QPS threshold. Default: 10
84+ -N No retry mode. Skip sleep and PID checking in load test startup, break immediately
85+ without retrying. Optional
8086EOF
8187}
8288
@@ -122,19 +128,28 @@ run_loadtest() {
122128 local tmp_file=$( mktemp)
123129 $command $threads_arg $qps_arg & > $tmp_file &
124130 LOADTEST_PID=$!
125- sleep 7
126- ps -p $LOADTEST_PID -o pid= > /dev/null && break
127- echo " Retrying $r of 3 to start load test..."
131+
132+ if [ " $no_retry_mode " = " 1" ]; then
133+ # No retry mode: skip sleep and PID checking, break immediately
134+ break
135+ else
136+ # Normal mode: sleep and check PID
137+ sleep 7
138+ ps -p $LOADTEST_PID -o pid= > /dev/null && break
139+ benchreps_tell_state " Retrying $r of 3 to start load test..."
140+ fi
128141 done
129142
130143 # wait for time
131144 sleep $experiment_time
145+ benchreps_tell_state " after sleeping for experiment_time=${experiment_time} seconds"
132146
133147 # send SIGINT to the command
134148 kill -SIGINT $LOADTEST_PID
135149
136150 # wait for results to show up and queries to drain
137151 sleep $wait_time
152+ benchreps_tell_state " after sleeping for wait_time=${wait_time} seconds"
138153
139154 # check file for QPS
140155 if grep -q " #: [0-9]\+.\([0-9]\+\)\? QPS" $tmp_file ; then
@@ -216,9 +231,12 @@ load_test_retries=3
216231output_csv_file=" "
217232fixed_qps=" "
218233auto_driver_threads=" "
234+ qps_threshold=" "
235+ max_warmup_iterations=10
236+ no_retry_mode=" "
219237
220238OPTIND=1 # Reset is necessary if getopts was used previously in the script. It is a good idea to make this local in a function.
221- while getopts " ht:f:w:m:s:q:ao:" opt; do
239+ while getopts " ht:f:w:m:s:q:ao:r:x:N " opt; do
222240 case " $opt " in
223241 h)
224242 show_help
@@ -249,6 +267,15 @@ while getopts "ht:f:w:m:s:q:ao:" opt; do
249267 o)
250268 output_csv_file=$OPTARG
251269 ;;
270+ r)
271+ qps_threshold=$OPTARG
272+ ;;
273+ x)
274+ max_warmup_iterations=$OPTARG
275+ ;;
276+ N)
277+ no_retry_mode=1
278+ ;;
252279 ' ?' )
253280 show_help >&2
254281 exit 1
@@ -322,8 +349,54 @@ if [ "$warmup_time" -gt 0 ]; then
322349 benchreps_tell_state " before warmup"
323350 saved_experiment_time=" $experiment_time "
324351 experiment_time=" $warmup_time "
325- run_loadtest peak_qps measured_latency
352+
353+ if [ -n " $qps_threshold " ]; then
354+ # Dynamic QPS-based warmup
355+ previous_qps=0
356+ warmup_iteration=0
357+
358+ while [ $warmup_iteration -lt $max_warmup_iterations ]; do
359+ run_loadtest current_qps measured_latency
360+ benchreps_tell_state " after iteration $warmup_iteration "
361+ printf " warmup iteration %d: qps = %.2f, latency = %.2f\n" $warmup_iteration $current_qps $measured_latency >> $BREPS_LFILE
362+
363+ # Skip first warmup iteration, always do the second round
364+ if [ $warmup_iteration -gt 1 ]; then
365+ # Calculate percentage increase: (current - previous) / previous * 100
366+ if [ $( echo " $previous_qps > 0" | bc) -eq 1 ]; then
367+ qps_increase_percentage=$( echo " scale=5; ($current_qps - $previous_qps ) / $previous_qps * 100" | bc)
368+ # Convert to absolute value for comparison
369+ # qps_increase_abs=$(echo "scale=5; ($qps_increase_percentage^2)^0.5" | bc)
370+ # qps_increase_check=$(echo "$qps_increase_abs <= $qps_threshold" | bc)
371+ qps_increase_check=$( echo " $qps_increase_percentage <= $qps_threshold " | bc)
372+
373+ if [ $qps_increase_check -eq 1 ]; then
374+ printf " QPS steady state reached. QPS increase percentage (%.2f%%) is less than threshold (%.2f%%)\n" $qps_increase_percentage $qps_threshold >> $BREPS_LFILE
375+ break
376+ fi
377+ else
378+ # If previous_qps is 0, skip the check for this iteration
379+ printf " Previous QPS is 0, skipping threshold check for iteration %d\n" $warmup_iteration >> $BREPS_LFILE
380+ fi
381+ fi
382+
383+ previous_qps=$current_qps
384+ warmup_iteration=$(( warmup_iteration + 1 ))
385+
386+ # Wait between warmup iterations (except for the last one)
387+ if [ $warmup_iteration -lt $max_warmup_iterations ]; then
388+ sleep $wait_time
389+ fi
390+ done
391+
392+ peak_qps=$current_qps
393+ else
394+ # Original fixed warmup time
395+ run_loadtest peak_qps measured_latency
396+ fi
397+
326398 printf " warmup qps = %.2f, latency = %.2f\n" $peak_qps $measured_latency
399+ echo " warmup qps = $peak_qps , latency = $measured_latency " >> $BREPS_LFILE
327400 benchreps_tell_state " after warmup"
328401 experiment_time=" $saved_experiment_time "
329402fi
@@ -338,13 +411,16 @@ if [[ -n "$fixed_qps" ]]; then
338411 collect_perf_record &
339412 fi
340413 run_loadtest measured_qps measured_latency $fixed_qps
414+
341415 printf " final requested_qps = %.2f, measured_qps = %.2f, latency = %.2f\n" $fixed_qps $measured_qps $measured_latency
416+ echo " final requested_qps = $fixed_qps , measured_qps = $measured_qps , latency = $measured_latency " >> $BREPS_LFILE
342417 benchreps_tell_state " after fixed_qps_single"
343418 else
344419 for fixed_qps_el in $fixed_qps_array ; do
345420 benchreps_tell_state " before fixed_qps_iter $fixed_qps_el "
346421 run_loadtest measured_qps measured_latency $fixed_qps_el
347422 printf " final requested_qps = %.2f, measured_qps = %.2f, latency = %.2f\n" $fixed_qps_el $measured_qps $measured_latency
423+ echo " final requested_qps = $fixed_qps_el , measured_qps = $measured_qps , latency = $measured_latency " >> $BREPS_LFILE
348424 benchreps_tell_state " after fixed_qps_iter $fixed_qps_el "
349425 sleep 7 # wait between iterations
350426 done
0 commit comments