1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
//! Cache-blocking table for the packed GEMM, tuned for an Intel Core Ultra 5 125H
//! (hybrid: P-cores with 48 KB L1d and 2 MB L2, E-core clusters sharing 2 MB L2, 18 MB shared L3).
//!
//! Sizes are in elements. `mc` and `nc` are the *largest* task rectangle; the driver shrinks
//! them for small problems so that every core gets several tasks. All values are multiples of the
//! register tile (`MR`, `NR`).
/// Cache block sizes for one element type.
pub
/// Rows of the register tile. Six broadcasts feed two B vectors: 12 accumulators + 2 B + 1 A
/// vector = 15 of the 16 ymm registers.
pub const MR: usize = 6;
/// f64 register tile columns: two 4-lane AVX2 vectors.
pub const NR_F64: usize = 8;
/// f32 register tile columns: two 8-lane AVX2 vectors.
pub const NR_F32: usize = 16;
pub const F64: Blocking = Blocking ;
pub const F32: Blocking = Blocking ;
/// Widest column range whose packed B slab (`kc * 4096` elements, 8 MiB for f64) is built at once.
/// Bounds the shared workspace for very wide outputs while fitting the 18 MiB L3.
pub const SLAB_COLUMNS: usize = 4096;
/// `m * n * k` multiply-adds below which the product stays on the calling thread (about a 200^3
/// product, ~0.3 ms serial): below this the rayon fork/join costs more than the extra cores save.
/// Measured with `examples/gemm_probe.rs --small`: f64 breaks even near n=128-192, f32 near 200-256.
pub const PARALLEL_WORK: usize = 1 << 23;
/// The driver shrinks task rectangles until there are at least this many tasks per rayon thread,
/// so that work stealing can give fast P-cores more blocks than slow E-cores. Larger values were
/// not measurably faster (1, 2, 4 and 8 tried) and pay more packing overhead.
pub const TASKS_PER_THREAD: usize = 2;