/home/noah/src/trueno/src/tiling/prefetch.rs
Line | Count | Source |
1 | | //! Prefetch locality hints for cache optimization. |
2 | | |
3 | | use super::geometry::{TcbGeometry, TcbLevel}; |
4 | | |
5 | | /// Prefetch locality hint |
6 | | #[derive(Debug, Clone, Copy)] |
7 | | pub enum PrefetchLocality { |
8 | | /// Non-temporal (streaming, evict soon) |
9 | | NonTemporal, |
10 | | /// L3 cache |
11 | | T2, |
12 | | /// L2 cache |
13 | | T1, |
14 | | /// L1 cache (highest priority) |
15 | | T0, |
16 | | } |
17 | | |
18 | | /// Calculate optimal prefetch distance based on tile geometry and cache level |
19 | | /// |
20 | | /// Per Ding & Kennedy (2004): distance = memory_latency / compute_time_per_iter |
21 | | #[must_use] |
22 | 0 | pub fn optimal_prefetch_distance(geometry: &TcbGeometry, level: TcbLevel) -> usize { |
23 | | // Approximate cycles per micro-tile |
24 | 0 | let compute_cycles = geometry.m as usize * geometry.n as usize * geometry.k as usize / 8; |
25 | | |
26 | | // Memory latency in cycles (approximate for modern x86) |
27 | 0 | let mem_latency = match level { |
28 | 0 | TcbLevel::Micro => 4, // L1: ~4 cycles |
29 | 0 | TcbLevel::Midi => 12, // L2: ~12 cycles |
30 | 0 | TcbLevel::Macro => 40, // L3: ~40 cycles |
31 | | }; |
32 | | |
33 | | // Distance = latency / compute_time, minimum 1 |
34 | 0 | (mem_latency / compute_cycles.max(1)).max(1) |
35 | 0 | } |