Skip to content

Commit b0abf52

Browse files
charles-typfacebook-github-bot
authored andcommitted
DCPerf: drop corrupt first perf interval from AMD report
Summary: On Turin (AMD EPYC 9D25 / Zen5), DCPerf `sleepbench` `overall-metrics.csv` reported a DRAM Read BW of ~620 GB/s — above the part's 512 GB/s physical ceiling. Root cause: the first `perf stat -I` interval is corrupt. The uncore/DF memory-controller counters report a cumulative startup value on their first read, and the first interval's duration is often irregular, so its derived rate (~2,454 GB/s here, ~4.8x the max) is physically impossible. Nothing dropped or clamped that first sample before it was averaged into the summary. Fix in `perfutils/generate_amd_perf_report.py`: add `drop_first_interval()`, called in `main()` after metrics are built and before aggregation/timeseries emission. It drops the first interval (`num_sockets` rows, one per socket) from every metric series so the summary and the timeseries stay aligned and physically meaningful. Short runs (series <= `num_sockets`) are left untouched to avoid collapsing to empty. Excluding the first sample, sustained DRAM read ~252 GB/s (valid). [Session trajectory link](https://www.internalfb.com/intern/devai/devmate/inspector/?id=8ff846bd-428a-4c33-8fa7-3c6264d4c96a) Differential Revision: D110798470
1 parent 2f5051e commit b0abf52

1 file changed

Lines changed: 20 additions & 0 deletions

File tree

perfutils/generate_amd_perf_report.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2303,6 +2303,24 @@ def zen5es_total_cxl_write_bw_mbs(grouped_df):
23032303
}
23042304

23052305

2306+
def drop_first_interval(metrics, num_samples):
2307+
"""Drop the first perf-stat interval from every metric's time series.
2308+
2309+
The uncore/DF memory-controller counters report a cumulative startup value
2310+
on their first ``perf stat -I`` read, and the first interval's duration is
2311+
often irregular, so the first sample's derived rates (e.g. DRAM bandwidth)
2312+
can exceed the hardware's physical limits. Excluding it keeps both the
2313+
aggregated summary and the emitted time series physically meaningful. One
2314+
interval spans ``num_samples`` rows (one per socket). Series shorter than
2315+
that are left untouched so short runs don't collapse to empty.
2316+
"""
2317+
if any(m["series"].size <= num_samples for m in metrics):
2318+
return metrics
2319+
for m in metrics:
2320+
m["series"] = m["series"].iloc[num_samples:]
2321+
return metrics
2322+
2323+
23062324
def aggregate_stats(derived_metric):
23072325
derived_series = derived_metric["series"]
23082326
prefix = derived_metric.get("prefix", 1.0)
@@ -2599,6 +2617,8 @@ def main(
25992617
)
26002618
return
26012619

2620+
filtered_metrics = drop_first_interval(filtered_metrics, get_num_sockets(df))
2621+
26022622
shortest_series = max(filtered_metrics, key=lambda m: m["series"].size)
26032623
df_metrics = concat_series(filtered_metrics, shortest_series)
26042624
if series:

0 commit comments

Comments
 (0)