A critical stride is a memory-access spacing that repeatedly maps addresses to the same cache set. The resulting conflict misses waste most of the cache, even when the accessed data would otherwise fit. section 12.1.5
The 512-column mistake
On a 32 KB, eight-way L1D cache with 64 sets and 64-byte cache lines, the critical stride is 64 × 64 bytes = 4 KB. Four kilobytes contain 512 int64 elements, so a 512-column matrix repeatedly targets the same cache set. calculateSum512 therefore has a poor cache distribution, while the otherwise identical calculateSum513 avoids that exact stride. section 12.1.5
func calculateSum512(s [][512]int64) int64 { #1
var sum int64
for i := 0; i < len(s); i++ {
for j := 0; j < 8; j++ {
sum += s[i][j]
}
}
return sum
}
func calculateSum513(s [][513]int64) int64 { #2
// Same implementation as calculateSum512
}
Compare the two Go function shapes while investigating why changing the matrix width from 512 to 513 columns can produce a large benchmark difference. section 12.1.5
Use these checks when a regular access pattern produces unexpectedly poor performance:
- Inspect the access stride against the target cache's line size and set count; a critical stride can use only one cache set instead of distributing accesses across the cache. section 12.1.5
- Treat a dimension change such as 512 to 513 as architecture-dependent rather than universally optimal, because different production cache architectures can change benchmark results. section 12.1.5
- Validate suspected cache effects on hardware resembling production instead of relying on a micro-benchmark run on a different system. section 12.1.5
