Run a single C++ benchmark and return total ops/sec. For multi-phase tests (e.g., rw1 with put+get phases), returns the sum of ops/sec across all phases, matching how C++ mttest reports totals.
(
mttest_path: Path,
threads: int,
duration: int,
test: str,
pin: bool = False,
quiet: bool = False,
verbose: bool = False,
)
| 100 | |
| 101 | |
| 102 | def run_cpp_benchmark( |
| 103 | mttest_path: Path, |
| 104 | threads: int, |
| 105 | duration: int, |
| 106 | test: str, |
| 107 | pin: bool = False, |
| 108 | quiet: bool = False, |
| 109 | verbose: bool = False, |
| 110 | ) -> Optional[float]: |
| 111 | """Run a single C++ benchmark and return total ops/sec. |
| 112 | |
| 113 | For multi-phase tests (e.g., rw1 with put+get phases), returns the sum |
| 114 | of ops/sec across all phases, matching how C++ mttest reports totals. |
| 115 | """ |
| 116 | cmd = [str(mttest_path), f"-j{threads}", f"-d{duration}"] |
| 117 | if pin: |
| 118 | cmd.append("-p") |
| 119 | cmd.append(test) |
| 120 | |
| 121 | if not quiet: |
| 122 | print(f" Running C++ {test}...", end="", flush=True, file=sys.stderr) |
| 123 | |
| 124 | try: |
| 125 | # Timeout: duration * 2 for two-phase tests (put + get) + buffer |
| 126 | timeout = duration * 3 + 30 |
| 127 | result = subprocess.run(cmd, capture_output=True, text=True, timeout=timeout) |
| 128 | except subprocess.TimeoutExpired: |
| 129 | if not quiet: |
| 130 | print(" timeout", file=sys.stderr) |
| 131 | return None |
| 132 | except Exception as e: |
| 133 | if not quiet: |
| 134 | print(f" error: {e}", file=sys.stderr) |
| 135 | return None |
| 136 | |
| 137 | # Check for non-zero exit code |
| 138 | if result.returncode != 0: |
| 139 | if not quiet: |
| 140 | print(f" exit code {result.returncode}", file=sys.stderr) |
| 141 | if verbose: |
| 142 | print(f" stdout: {result.stdout[:500]}", file=sys.stderr) |
| 143 | print(f" stderr: {result.stderr[:500]}", file=sys.stderr) |
| 144 | return None |
| 145 | |
| 146 | output = result.stderr |
| 147 | |
| 148 | # Parse JSON lines from stderr |
| 149 | ops_per_sec_values: List[float] = [] |
| 150 | puts_per_sec_values: List[float] = [] |
| 151 | gets_per_sec_values: List[float] = [] |
| 152 | json_lines_found = 0 |
| 153 | |
| 154 | for line in output.splitlines(): |
| 155 | brace_idx = line.find("{") |
| 156 | if brace_idx == -1: |
| 157 | continue |
| 158 | json_lines_found += 1 |
| 159 | try: |