我想研究二级缓存未命中对CPU功耗的影响。为了衡量这一点,我必须创建一个逐步增加工作集大小的基准,以便核心活动(每个周期执行的微操作)和L2活动(每个周期的L2请求)保持不变,但L2未命中与L2请求的比率增加。
任何人都可以向我展示C程序的一个例子,它强迫" N" L2缓存未命中数?
答案 0 :(得分:2)
通常可以通过随机访问大于缓存级别 1 的工作集来强制某些缓存级别的缓存未命中。
您可能会认为任何给定负载的概率都是:p(hit) = min(100, C / W)
和p(miss) = 1 - p(hit)
其中p(hit)
和p(miss)
是概率命中和未命中,C
是相关的缓存大小,W
是工作集大小。因此,对于50%的未命中率,请使用两倍高速缓存大小的工作集。
快速查看上面的公式可以看出p(miss)
永远不会是100%,因为C/W
只会变为0,因为W会变为无穷大(并且你可能无法承受无穷大) RAM量)。所以你的选择是:
获得"足够接近"通过使用非常大的工作集(例如,4 GB为256 KB提供99%+错失机会),并假装您的未命中率为100%。
应用公式确定实际预期的未命中数。例如,如果您使用的工作大小为2560 KB,而二级缓存为256 KB,则错过率为90%。因此,如果你想检查1000次未命中的效果,你应该进行1000 / 0.9 = ~1111内存访问,以获得大约1,000次未命中。
使用任何近似方法,但实际计算使用CPU上的性能计数器单元产生的未命中数。例如,在Linux上,您可以使用PAPI,或者在Linux和Windows上使用英特尔PCM(如果您使用的是英特尔硬件)。
使用"几乎随机"强迫你想要的失误次数的方法。上面的公式对于随机访问是有效的,但是如果你选择访问模式以便它是随机的,并且它不会重复"最近"访问,你可以得到100%的错过率。这里"最近"表示访问可能仍在缓存中的缓存行。计算这意味着什么是棘手的,并且详细地依赖于缓存的关联性和替换算法,但是如果你不重复在最后cache_size * 10
次访问中发生的任何访问,你应该是漂亮的安全
至于C代码,您至少应该向我们展示您尝试过的内容。基本概要是创建一个字节或整数或任何具有所需大小的向量,然后随机访问该向量。如果您使每次访问都依赖于先前的访问(例如,使用整数读取来计算下一次读取的索引),您还将粗略测量该级别的缓存的延迟。如果访问是独立的,那么您可能会立即有几个未完成的未命中错误,并且每单位时间会有更多未命中。您感兴趣的是哪一个取决于您正在学习的内容。
对于跨不同步幅和工作集大小进行此类内存测试的开源项目,请查看TinyMemBench。
1 对于在核心之间共享的缓存级别(例如,对于最近的英特尔芯片通常为L3),这会变得有点棘手 - 但是如果您的机器在测试时非常安静,它应该可以正常工作