Skip to content

Commit d121a79

Browse files
committed
feature(perf): support latte in gradual grow throughput test
Gradual throughput test uses several substitution variables and 2 of them, called "$threads" and "$throttle", are not compatible "as-is" with the latte benchmarking tool. First, Latte has "--threads=N" and "--concurrency=M" parameters whereas cassandra-stress has only "--threads". So, latte's values must be multiplied to get CS's value. Second, latte uses "--rate=100" not "fixed=100/s" or "throttle=100s" like CS does. Knowing above, add appropriate parsing of the latte command to support existing substitution values. Example: Following CS command: cassandra-stress mixed cl=QUORUM duration=$duration -mode cql3 native \ -rate 'threads=$threads $throttle' \ -col 'size=FIXED(1024) n=FIXED(1)' -pop seq=15000001..20000000 Can be simulated by the following Latte command: latte run --function=write,read --tag=mixed --sampling=10s --duration=$duration \ $throttle --threads=7 --concurrency=$threads --consistency=QUORUM -P key_size=10 -P column_size=1024 -P column_count=1 -P row_count=20000000 -P offset=15000001 data_dir/latte/latte_cs_alike.rn In case of Latte we specify "--threads" explicitly as (N-1) value where N is number of CPU cores on loader nodes.
1 parent b871eb6 commit d121a79

File tree

2 files changed

+35
-3
lines changed

2 files changed

+35
-3
lines changed

performance_regression_gradual_grow_throughput.py

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import math
12
import pathlib
23
import time
34
from enum import Enum
@@ -10,6 +11,7 @@
1011
from sdcm.utils.common import skip_optional_stage
1112
from sdcm.sct_events import Severity
1213
from sdcm.sct_events.system import TestFrameworkEvent
14+
from sdcm.stress.latte_thread import find_latte_threads_num
1315
from sdcm.results_analyze import PredefinedStepsTestPerformanceAnalyzer
1416
from sdcm.utils.decorators import latency_calculator_decorator
1517
from sdcm.utils.latency import calculate_latency, analyze_hdr_percentiles
@@ -32,6 +34,17 @@ class Workload(NamedTuple):
3234
step_duration: str
3335

3436

37+
def process_stress_threads_number(stress_cmd: str, num_threads: int):
38+
# NOTE: latte has 2 separate options - '--threads' and '--concurrency'.
39+
# CS's threads == latte threads multiple of 'concurrency'
40+
# Example: 620 CS threads = 7 latte threads with concurrency as '89' per each thread (623)
41+
if "latte " in stress_cmd:
42+
latte_threads_num = find_latte_threads_num(stress_cmd)
43+
return math.ceil(num_threads / latte_threads_num)
44+
45+
return num_threads
46+
47+
3548
class PerformanceRegressionPredefinedStepsTest(PerformanceRegressionTest): # pylint: disable=too-many-instance-attributes
3649
"""
3750
This class presents new performance test that run gradual increased throughput steps.
@@ -191,8 +204,9 @@ def run_step(self, stress_cmds, current_throttle, num_threads, step_duration):
191204
stress_queue = []
192205
for stress_cmd in stress_cmds:
193206
params = {"round_robin": True, "stats_aggregate_cmds": False}
207+
current_num_threads = process_stress_threads_number(stress_cmd, num_threads)
194208
stress_cmd_to_run = stress_cmd.replace(
195-
"$threads", f"{num_threads}").replace("$throttle", f"{current_throttle}")
209+
"$threads", f"{current_num_threads}").replace("$throttle", f"{current_throttle}")
196210
if step_duration is not None:
197211
stress_cmd_to_run = stress_cmd_to_run.replace("$duration", step_duration)
198212
params.update({'stress_cmd': stress_cmd_to_run})
@@ -225,7 +239,15 @@ def run_gradual_increase_load(self, workload: Workload, stress_num, num_loaders,
225239

226240
for throttle_step in workload.throttle_steps:
227241
self.log.info("Run cs command with rate: %s Kops", throttle_step)
228-
current_throttle = f"fixed={int(int(throttle_step) // (num_loaders * stress_num))}/s" if throttle_step != "unthrottled" else ""
242+
if throttle_step == "unthrottled":
243+
current_throttle = ""
244+
else:
245+
throttle_value = int(int(throttle_step) // (num_loaders * stress_num))
246+
if "latte " in workload.cs_cmd_tmpl[0]:
247+
current_throttle = f"--rate={throttle_value}"
248+
else:
249+
current_throttle = f"fixed={throttle_value}/s"
250+
229251
run_step = ((latency_calculator_decorator(legend=f"Gradual test step {throttle_step} op/s",
230252
cycle_name=throttle_step))(self.run_step))
231253
results, _ = run_step(stress_cmds=workload.cs_cmd_tmpl, current_throttle=current_throttle,
@@ -304,7 +326,8 @@ def warmup_cache(self, stress_cmd_templ, num_threads):
304326
stress_queue = []
305327
for stress_cmd in stress_cmd_templ:
306328
params = {"round_robin": True, "stats_aggregate_cmds": False}
307-
stress_cmd_to_run = stress_cmd.replace("$threads", str(num_threads))
329+
current_num_threads = process_stress_threads_number(stress_cmd, num_threads)
330+
stress_cmd_to_run = stress_cmd.replace("$threads", str(current_num_threads))
308331
params.update({'stress_cmd': stress_cmd_to_run})
309332
# Run all stress commands
310333
self.log.debug('RUNNING warm up stress cmd: %s', stress_cmd_to_run)

sdcm/stress/latte_thread.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636

3737
LATTE_FN_NAME_RE = '(?:-f|--function)[ =]([\w\s\d:,]+)|--functions[ =]([\w\s\d:,]+)'
3838
LATTE_TAG_RE = r'--tag(?:\s+|=)([\w-]+(?:,[\w-]+)*)\b'
39+
LATTE_THREADS_RE = r"(?:\s|^)(?:-t[= ]|--threads[= ]?)(\d+)(?:\s|$)"
3940
LOGGER = logging.getLogger(__name__)
4041

4142

@@ -66,6 +67,14 @@ def find_latte_tags(stress_cmd):
6667
return tags
6768

6869

70+
def find_latte_threads_num(stress_cmd):
71+
matches = re.findall(LATTE_THREADS_RE, stress_cmd)
72+
if matches:
73+
return int(matches[0])
74+
# NOTE: threads were not specified, assume latte's default as `1`
75+
return 1
76+
77+
6978
def get_latte_operation_type(stress_cmd):
7079
write_found, counter_write, read_found, counter_read = False, False, False, False
7180
for fn in find_latte_fn_names(stress_cmd):

0 commit comments

Comments
 (0)