Skip to content

Commit a05ce2c

Browse files
committed
Fix the perf period calculation
1 parent 4b956d2 commit a05ce2c

File tree

2 files changed

+55
-3
lines changed

2 files changed

+55
-3
lines changed

bench_runner/scripts/profiling_plot.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from collections import defaultdict
1010
import csv
1111
import functools
12+
import json
1213
from operator import itemgetter
1314
from pathlib import Path
1415
import re
@@ -40,6 +41,7 @@
4041
"_PyPegen_.+",
4142
"_PyStack_.+",
4243
"_PyVectorcall_.+",
44+
"_TAIL_CALL_.+",
4345
"advance",
4446
"call_instrumentation_vector.*",
4547
"initialize_locals",
@@ -414,6 +416,52 @@ def plot_pie(categories: list[tuple[float, str]], output_filename: PathLike):
414416
fig.savefig(output_filename, dpi=200)
415417

416418

419+
def handle_tail_call_stats(
420+
categories: defaultdict[str, defaultdict[tuple[str, str], float]],
421+
output_prefix: Path,
422+
):
423+
tail_call_stats = defaultdict(float)
424+
total_time = 0.0
425+
for (_, sym), self_time in categories["interpreter"].items():
426+
if (bytecode := sym.removeprefix("_TAIL_CALL_")) != sym:
427+
tail_call_stats[bytecode] += self_time
428+
total_time += self_time
429+
430+
with Path("pystats.json").open() as fd:
431+
pystats = json.load(fd)
432+
433+
pystats_bytecodes = defaultdict(int)
434+
total_count = 0
435+
for key, val in pystats.items():
436+
if match := re.match(r"opcode\[(.+)\]\.execution_count", key):
437+
pystats_bytecodes[match.group(1)] += val
438+
total_count += val
439+
440+
if len(tail_call_stats) == 0:
441+
return
442+
443+
with open(output_prefix.with_suffix(".tail_calls.csv"), "w") as csvfile:
444+
writer = csv.writer(csvfile, dialect="unix")
445+
writer.writerow(
446+
["Bytecode", "% time", "count", "% count", "time per count (ns)"]
447+
)
448+
for bytecode, seconds in sorted(
449+
tail_call_stats.items(), key=itemgetter(1), reverse=True
450+
):
451+
count = pystats_bytecodes[bytecode]
452+
if count == 0:
453+
continue
454+
writer.writerow(
455+
[
456+
bytecode,
457+
f"{seconds / total_time:.02%}",
458+
count,
459+
f"{count / total_count:.02%}",
460+
f"{(seconds / count) * 1e9:03f}",
461+
]
462+
)
463+
464+
417465
def _main(input_dir: PathLike, output_prefix: PathLike):
418466
input_dir = Path(input_dir)
419467
output_prefix = Path(output_prefix)
@@ -427,6 +475,8 @@ def _main(input_dir: PathLike, output_prefix: PathLike):
427475

428476
with output_prefix.with_suffix(".md").open("w") as md:
429477
for csv_path in sorted(input_dir.glob("*.csv")):
478+
if "tail_calls.csv" in csv_path.name:
479+
continue
430480
handle_benchmark(csv_path, md, results, categories)
431481

432482
sorted_categories = sorted(
@@ -454,6 +504,8 @@ def _main(input_dir: PathLike, output_prefix: PathLike):
454504
plot_bargraph(results, sorted_categories, output_prefix.with_suffix(".svg"))
455505
plot_pie(sorted_categories, output_prefix.with_suffix(".pie.svg"))
456506

507+
handle_tail_call_stats(categories, output_prefix)
508+
457509

458510
def main():
459511
parser = argparse.ArgumentParser(

bench_runner/scripts/run_benchmarks.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -189,9 +189,9 @@ def perf_to_csv(lines: Iterable[str], output: PathLike):
189189
else:
190190
_, period, command, _, symbol, shared, _ = line.split(maxsplit=6)
191191
pid, command = command.split(":")
192-
self_time = float(int(period)) / total
193-
if self_time > 0.0:
194-
rows.append([self_time, pid, command, shared, symbol])
192+
period = float(period)
193+
if period > 0.0:
194+
rows.append([period, pid, command, shared, symbol])
195195

196196
rows.sort(key=itemgetter(0), reverse=True)
197197

0 commit comments

Comments
 (0)