Skip to content

Commit 3d0e6af

Browse files
fix(asap-tools): keep perf script conversion on remote
1 parent 4d1415d commit 3d0e6af

5 files changed

Lines changed: 16 additions & 30 deletions

File tree

‎asap-tools/docs/configuration.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,8 +177,8 @@ All profiling options are in the `profiling` section and are **monitoring** feat
177177
profiling.query_engine=true
178178
```
179179

180-
**Output:** Raw `perf.data` recordings and `perf archive` symbol archives are
181-
saved to the experiment output directory. Run
180+
**Output:** Raw `perf.data` recordings and remote `perf script --header` output
181+
are saved to the experiment output directory. Run
182182
`experiments/postprocess_query_engine_profiles.sh` locally after the experiment
183183
to generate scripts, folded stacks, and flamegraphs.
184184

‎asap-tools/docs/query-engine-profiling.md‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@ Set `profiling.query_engine: true` and
55

66
The remote workflow builds and launches the separate
77
`target/release/query_engine_rust_fp` binary, records compact frame-pointer
8-
call chains with `perf record`, and archives the symbols with `perf archive`.
9-
It does not run `perf script` remotely.
8+
call chains with `perf record`, and converts the recording to a symbolized
9+
`perf.script` with `perf script --header` on the remote node. FP makes this
10+
conversion fast enough to complete before the experiment output is rsynced.
1011

1112
After `experiment_run_e2e.py` rsyncs the experiment output back locally, run:
1213

@@ -15,7 +16,8 @@ After `experiment_run_e2e.py` rsyncs the experiment output back locally, run:
1516
experiment_outputs/<experiment>/sketchdb/query_engine_profiles
1617
```
1718

18-
This produces, for each `perf_*.data` file:
19+
This reuses the remote `.script` file when present and produces, for each
20+
`perf_*.data` file:
1921

2022
- `.script`: symbolized Perf samples;
2123
- `.folded`: collapsed stacks for Speedscope or FlameGraph;

‎asap-tools/experiments/experiment_utils/services/query_engine.py‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -361,8 +361,6 @@ def _start_bare_metal(
361361
# which execs argv[0] directly rather than re-parsing through a
362362
# shell -- a bare `VAR=val` prefix would make nohup try (and
363363
# fail) to exec "TZ=UTC" itself as the program name.
364-
f"test -x {binary_path} || "
365-
f"{{ echo 'Missing query engine binary: {binary_path}'; exit 1; }}; "
366364
f"env TZ=UTC {binary_path}"
367365
f" --config-file {output_dir}/engine_config.yaml"
368366
f" > {output_dir}/query_engine_rust.out 2>&1 &"

‎asap-tools/experiments/postprocess_query_engine_profiles.sh‎

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,7 @@ for data_file in "${data_files[@]}"; do
3535
script_file="$stem.script"
3636
folded_file="$stem.folded"
3737
svg_file="$stem.svg"
38-
archive_file="$data_file.tar.bz2"
39-
symfs_directory="${stem}.symbols"
40-
41-
if [[ -f "$archive_file" ]]; then
42-
mkdir -p "$symfs_directory"
43-
tar --overwrite -xjf "$archive_file" -C "$symfs_directory"
44-
perf script --header -i "$data_file" --symfs "$symfs_directory" > "$script_file"
45-
else
38+
if [[ ! -f "$script_file" ]]; then
4639
perf script --header -i "$data_file" > "$script_file"
4740
fi
4841

‎asap-tools/experiments/remote_monitor.py‎

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import subprocess
66
import yaml
77
import signal
8-
import tempfile
98
from loguru import logger
109

1110
from typing import List
@@ -217,29 +216,23 @@ def stop_profiling_query_engine_pids(qe_perf_procs, store: bool):
217216
logger.debug("Stopped profiling for query engine pids")
218217

219218

220-
def archive_query_engine_perf_data(experiment_output_dir):
219+
def convert_query_engine_perf_data(experiment_output_dir):
221220
qe_profiles_dir = os.path.join(experiment_output_dir, "query_engine_profiles")
222221
data_files = [
223222
os.path.join(qe_profiles_dir, f)
224223
for f in os.listdir(qe_profiles_dir)
225224
if f.startswith("perf_") and f.endswith(".data")
226225
]
227226
for data_file in data_files:
228-
archive_file = f"{data_file}.tar.bz2"
229-
logger.debug(f"Archiving {data_file} to {archive_file}")
230-
with tempfile.TemporaryDirectory(dir=qe_profiles_dir) as archive_dir:
227+
script_file = data_file.replace(".data", ".script")
228+
logger.debug(f"Converting {data_file} to {script_file}")
229+
with open(script_file, "w") as script_output:
231230
subprocess.run(
232-
["perf", "archive", data_file],
233-
cwd=archive_dir,
231+
["perf", "script", "--header", "-i", data_file],
232+
stdout=script_output,
234233
check=True,
235234
)
236-
generated_archive = os.path.join(archive_dir, "perf.data.tar.bz2")
237-
if not os.path.isfile(generated_archive):
238-
raise RuntimeError(
239-
f"perf archive did not produce expected file: {generated_archive}"
240-
)
241-
os.replace(generated_archive, archive_file)
242-
logger.debug(f"Finished archiving {data_file}")
235+
logger.debug(f"Finished converting {data_file}")
243236

244237

245238
# TODO Provide some way of specifying which hooks will be used
@@ -442,7 +435,7 @@ def main(args):
442435
if qe_flamegraph_procs:
443436
logger.debug("Stopping profiling for query engine pids")
444437
stop_profiling_query_engine_pids(qe_flamegraph_procs, store=True)
445-
archive_query_engine_perf_data(args.experiment_output_dir)
438+
convert_query_engine_perf_data(args.experiment_output_dir)
446439

447440
logger.debug("Stopping process monitors")
448441
monitor_info = process_monitor.stop_monitor(monitor, control_pipe, monitor_pipe)

0 commit comments

Comments
 (0)