use crate::sim::stats::{Formula, Meta, StatId, StatSource, Stats};
#[derive(Clone, Copy, Debug)]
pub struct CacheStatPaths {
pub hits: StatId,
pub misses: StatId,
pub mshr_hits: StatId,
pub blocked_requests: StatId,
pub fills: StatId,
pub evictions: StatId,
pub writebacks: StatId,
pub back_invalidations: StatId,
pub maintenance: StatId,
pub probes: StatId,
pub snoops: StatId,
pub snoop_invalidations: StatId,
pub snoop_downgrades: StatId,
pub upgrades: StatId,
pub upgrade_retries: StatId,
pub prefetches_issued: StatId,
pub prefetches_late: StatId,
pub prefetches_useful: StatId,
pub prefetches_unused: StatId,
pub prefetches_used: StatId,
pub prefetches_accuracy: StatId,
pub prefetches_page_crossing: StatId,
pub prefetches_dropped: StatId,
pub store_prefetches: StatId,
pub miss_rate: StatId,
}
impl CacheStatPaths {
#[must_use]
pub fn new(subject: &str) -> Self {
let path = |tail: &str| StatId::of(&format!("{subject}.{tail}"));
Self {
hits: path("hits"),
misses: path("misses"),
mshr_hits: path("mshr_hits"),
blocked_requests: path("blocked_requests"),
fills: path("fills"),
evictions: path("evictions"),
writebacks: path("writebacks"),
back_invalidations: path("back_invalidations"),
maintenance: path("maintenance"),
probes: path("probes"),
snoops: path("coherence.snoops"),
snoop_invalidations: path("coherence.invalidations"),
snoop_downgrades: path("coherence.downgrades"),
upgrades: path("coherence.upgrades"),
upgrade_retries: path("coherence.upgrade_retries"),
prefetches_issued: path("prefetches.issued"),
prefetches_late: path("prefetches.late"),
prefetches_useful: path("prefetches.useful"),
prefetches_unused: path("prefetches.unused"),
prefetches_used: path("prefetches.used"),
prefetches_accuracy: path("prefetches.accuracy"),
prefetches_page_crossing: path("prefetches.page_crossing"),
prefetches_dropped: path("prefetches.dropped"),
store_prefetches: path("prefetches.store_stream"),
miss_rate: path("miss_rate"),
}
}
}
impl StatSource for CacheStatPaths {
fn register(&self, s: &mut Stats) {
s.register(self.hits, Meta::events("requests answered from the tag array"));
s.register(self.misses, Meta::events("requests that started or joined a line fetch"));
s.register(self.mshr_hits, Meta::events("misses that joined an in-flight fetch"));
s.register(
self.blocked_requests,
Meta::events("requests queued while MSHRs or writeback buffer were full"),
);
s.register(self.fills, Meta::events("lines installed"));
s.register(self.evictions, Meta::events("valid lines replaced"));
s.register(self.writebacks, Meta::events("lines written to the next level"));
s.register(
self.back_invalidations,
Meta::events("lines dropped at the next level's request"),
);
s.register(self.maintenance, Meta::events("cache-maintenance operations passed through"));
s.register(self.probes, Meta::events("probes received on behalf of snoops"));
s.register(self.snoops, Meta::events("snoops received from the home agent"));
s.register(self.snoop_invalidations, Meta::events("snoops that took the line away"));
s.register(self.snoop_downgrades, Meta::events("snoops that left a shared copy"));
s.register(self.upgrades, Meta::events("permission requests for lines held Shared"));
s.register(
self.upgrade_retries,
Meta::events("permission grants that arrived after a snoop took the line"),
);
s.register(self.prefetches_issued, Meta::events("prefetch fetches started"));
s.register(
self.prefetches_late,
Meta::events("prefetch fetches a request joined before the fill"),
);
s.register(
self.prefetches_useful,
Meta::events("prefetched lines a request found once installed"),
);
s.register(
self.prefetches_unused,
Meta::events("prefetched lines dropped before any request found them"),
);
s.register(
self.prefetches_page_crossing,
Meta::events("prefetch candidates dropped at a 4 KiB page boundary"),
);
s.register(
self.prefetches_dropped,
Meta::events("prefetch requests dropped for want of an MSHR"),
);
s.register(
self.store_prefetches,
Meta::events("store-miss prefetches sent to the next level"),
);
s.derive(
self.prefetches_used,
Formula::Sum(vec![self.prefetches_useful, self.prefetches_late]),
Meta::events("prefetches a request used, late or not"),
);
s.derive(
self.prefetches_accuracy,
Formula::Div(self.prefetches_used, self.prefetches_issued),
Meta::ratio("share of issued prefetches a request used"),
);
s.derive(
self.miss_rate,
Formula::Ratio { numerator: self.misses, other: self.hits },
Meta::ratio("miss rate"),
);
}
}