yihong0618 和朋友们的频道 头像

消息来源频道

yihong0618 和朋友们的频道

@hyi0618

频道8,612 位成员公开可见0 人在线

yihong0618 和朋友们的频道

成员规模8,612 位成员
在线情况0 人在线
消息总数10,129 条消息
浏览量总数3,298,582 次浏览

在这个频道里搜索消息……

t.me/hyi0618

终于检查完这篇文章了: https://skoredin.pro/blog/golang/cpu-cache-friendly-go
TLDR,AI 文可能性很大,正确内容里夹着部分错误,误导性高,但具有启发性,需读者花时间检查错误和内化。
那我就不要脸地带大家读一遍吧😋
False Sharing: The Silent Killer
这第一小节就给非科班出身一个震撼,怀着巨大好奇让 AI 写 benchmark 又发现测不出差距转而痛骂 AI,但其实文章是对的,在多核 lock prefix insn 并行执行下 false sharing 真的可能导致六倍性能差距,见评论区 https://t.me/danteslimbo/5575
Measure Cache Misses (Linux)
我的评价是不如直接 perf stat -d 啥都有;此外 false sharing 在 TopdownL4 里。
Data-Oriented Design: Array of Structs vs Struct of Arrays
这是对的,也比较好理解。
Prefetching: Help the CPU Predict
这是对的,尤其要注意最后那个线性迭代本身就已经有 cpu prefetch,但在线性迭代里手动 prefetch 下一个 cacheline 依然能让性能 +25%
func SumLinearWithManualPrefetch(data []int, prefetchDistance int) int {
sum := 0
for i := 0; i < len(data); i++ {
j := i + prefetchDistance
if j < len(data) {
_ = data[j]
}
sum += data[i]
}
return sum
}
QC 前几天分享了一篇文章测试了 Go 程序迭代模式对 prefetch 的影响: https://lemire.me/blog/2025/08/15/predictable-memory-accesses-are-much-faster/
其中最令我印象深刻的结论是 bouncing access (读 a[i] 和 a[len-i] 一头一尾弹跳式非线性读)居然能有最好的性能,原因是指令级并行,我已有 perf 验证。
Hot/Cold Data Splitting
是对的,容易理解。
NUMA-Aware Allocation
没有条件测试🤬下一题
Branch Prediction Friendly Code
这是错的,错得非常彻底,因为 Go (1.22 ~ 1.24) 会把 if v > 128 { count++ } 编译成为无分支跳转的指令
0x000000000049fe33 <+19>: inc %rcx
0x000000000049fe36 <+22>: cmp $0x80,%rsi
0x000000000049fe3d <+29>: cmovg %rdi,%rdx
cmovg (条件 move) 保证了原文里 CountCondition 函数在有序或者无序输入下的分支预测错误率是一样低的。
Cache-Conscious Hash Table
居然是对的。RobinHoodMap Set 性能不行,但是 Get 指令可以达到 go map 的五倍性能,在小 value 的时候往后检查一个 cacheline 的 distance 性能真的很炸裂。
SIMD-Friendly Layouts
错误的,里面两个观点都是错的:
1. Padding for 16-byte alignment 可以让编译器编译出 SIMD 指令。实际上不需要 pad 也是 SIMD 指令,而且 pad 之后影响了 cache miss rate 导致性能下降。
2. _ [0]byte 可以强制结构体对齐 cacheline。错误的,随便测一下就知道是错的。
其实我觉得 cache friendly 还只是高性能 CPU 程序的冰山一角,我今年学到的 CPU 指令级并发 (tma_ports_utilized_3m) 才是最黑魔法的,比如浮点乘法
sum = sum (b[i] c[i])
vs
sum += a[i] b[i] c[i]
前者比后者快了 1.5 倍 (0.842 vs 1.345 ns/elem),这些都是 x64 特供魔法,非常有趣。