Skip to content

Commit ddeef41

Browse files
committed
perf(xgmi): cache static link speeds, halving per-refresh cost
1 parent f1764dc commit ddeef41

1 file changed

Lines changed: 15 additions & 2 deletions

File tree

src/xgmi.rs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -251,10 +251,11 @@ pub fn read_all_xgmi_stats() -> io::Result<Vec<XgmiSnapshot>> {
251251
}
252252
let bdfs: Vec<Option<u64>> = handles.iter().map(|&h| read_bdf(api, h)).collect();
253253
let names = gpu_names(api, &handles);
254+
let speeds = link_speeds(api, &handles);
254255

255256
let mut snapshots = Vec::with_capacity(handles.len());
256257
for idx in 0..handles.len() {
257-
if let Some(snap) = read_processor_snapshot(api, &handles, &bdfs, names, idx) {
258+
if let Some(snap) = read_processor_snapshot(api, &handles, &bdfs, names, speeds, idx) {
258259
snapshots.push(snap);
259260
}
260261
}
@@ -274,6 +275,17 @@ fn gpu_names(api: &Amdsmi, handles: &[ffi::ProcessorHandle]) -> &'static [String
274275
})
275276
}
276277

278+
/// Per-GPU (bit_rate, bandwidth) Gb/s, read once and cached by GPU index:
279+
/// link speed is static and `amdsmi_get_pcie_info` costs ~0.5 ms per call —
280+
/// roughly half of the whole refresh when polled for every GPU each second.
281+
fn link_speeds(
282+
api: &Amdsmi,
283+
handles: &[ffi::ProcessorHandle],
284+
) -> &'static [(Option<f64>, Option<f64>)] {
285+
static SPEEDS: OnceLock<Vec<(Option<f64>, Option<f64>)>> = OnceLock::new();
286+
SPEEDS.get_or_init(|| handles.iter().map(|&h| read_link_speed(api, h)).collect())
287+
}
288+
277289
/// Flatten socket/processor enumeration into one ordered GPU handle list.
278290
/// This order defines `gpu_index` and matches amdsmi's accumulator indexing.
279291
fn enumerate_gpus(api: &Amdsmi) -> Vec<ffi::ProcessorHandle> {
@@ -319,6 +331,7 @@ fn read_processor_snapshot(
319331
handles: &[ffi::ProcessorHandle],
320332
bdfs: &[Option<u64>],
321333
names: &[String],
334+
speeds: &[(Option<f64>, Option<f64>)],
322335
idx: usize,
323336
) -> Option<XgmiSnapshot> {
324337
let handle = handles[idx];
@@ -330,7 +343,7 @@ fn read_processor_snapshot(
330343
let metrics = &metrics.value;
331344

332345
let gpu_name = names.get(idx).cloned().unwrap_or_default();
333-
let (bit_rate_gbps, speed_gbps) = read_link_speed(api, handle);
346+
let (bit_rate_gbps, speed_gbps) = speeds.get(idx).copied().unwrap_or((None, None));
334347
let (correctable_errors, uncorrectable_errors) = read_wafl_errors(api, handle);
335348

336349
let n = (metrics.num_links as usize).min(ffi::AMDSMI_MAX_NUM_XGMI_PHYSICAL_LINK);

0 commit comments

Comments
 (0)