CPU缓存实验结果与预期不符的原因咨询(对应博客Example1-2)
实验结果解析:缺页中断与页面级访问的核心影响
你的实验结果和预期的差异,核心是惰性内存分配带来的缺页中断开销,以及不同步长下内存访问模式的变化,具体拆解如下:
1. 内存分配的"幕后操作"
你用new int[size]申请的是虚拟内存空间,物理内存并不会立刻到位。只有当代码第一次执行arr[i] *=3写入操作时,操作系统才会触发写时缺页中断——这一步要完成虚拟地址到物理页的映射、分配物理内存,开销远大于普通内存访问(一次中断可能消耗数千个CPU周期)。
2. 步长≤1024(页面大小)时的耗时变化
你的MacBook Pro页面大小为4096字节,对应1024个int(每个int占4字节)。当步长≤1024时:
- 小步长(1、2、4):总循环次数极多(步长1时要执行16777216次),虽然每个页面仅触发1次缺页,但大量的算术运算、cache line读写会把缺页开销分摊到更多操作中,导致总耗时较高。
- 步长增大到16~1024:循环次数逐渐减少,同时CPU可以乱序执行这些无数据依赖的内存操作(每次访问不同的cache line、同一页面内的地址),流水线阻塞减少,耗时逐步下降并趋于稳定。
- 步长=1024:刚好每次访问一个新页面的第一个元素,循环次数等于总页面数(16384次),每个循环都触发一次缺页,此时耗时完全由缺页+单次内存读写的固定成本决定,数值趋于稳定。
3. 步长>1024时骤降的关键原因
当步长超过1024,每次访问会跳过至少一个完整页面:
- 步长=2048:每次跳过2个页面(8192字节),循环次数直接减半到8192次,对应的缺页次数也同步减半,总开销自然骤降为原来的一半左右(121ms→62ms)。
- 步长=4096:循环次数再减半,缺页次数也减半,耗时同步降低(62ms→32ms),以此类推,完全匹配你观察到的结果。
4. TLB的辅助影响(次要)
TLB(页表缓存)负责快速映射虚拟地址到物理地址:
- 步长≤1024时,访问集中在少量页面内,TLB命中率极高,不会额外增加开销。
- 步长>1024时,每次访问新页面可能触发TLB未命中,但此时缺页次数的大幅减少已经主导了耗时变化,TLB的影响可以忽略。
小提示:代码中的内存泄漏
你的代码未添加delete[] arr,每次循环都会占用新的虚拟内存。本次实验因循环次数少(最多16次),内存足够所以未影响结果,但长期运行会耗尽系统内存,建议补充内存释放逻辑。
内容的提问来源于stack exchange,提问作者Happytreat
相关产品推荐
相关产品推荐

