与高速缓存引用缓存未命中率相比,为什么缓存未命中指令比率是缓存性能的更好指标?

时间:2016-09-07 10:01:35

标签: algorithm performance caching performance-testing

我正在使用perf来测试理论上被证明是缓存友好算法的代码。

根据this article,缓存未命中指令是缓存性能的一个很好的指标。

  

缓存未命中与指令的比率将指示如何   缓存正在运行;比率越低越好。在这   例如,该比率为1.26%(6,605,955缓存未命中/ 525,543,766   说明)。因为成本差异比较大   RAM存储器和高速缓存访​​问之间(100周期vs <20周期)   即使是缓存未命中率的小改进也可以显着提高   性能。如果每条指令的缓存未命中率超过5%,   需要进一步调查。

然而,当我像这样运行perf:

perf stat -B -e cache-references,cache-misses,instructions ./td 1.txt 2.txt

Perf将打印以下内容:

Performance counter stats for './td 1.txt 2.txt':

    93,497,101      cache-references                                            
    56,452,246      cache-misses              #   60.379 % of all cache refs    
 8,115,626,200      instructions             

   2.509309040 seconds time elapsed

因此,它更多地关注缓存引用缓存未命中率而不是文章中建议的那个。

缓存未命中缓存引用率似乎非常糟糕,60%,这意味着我的应用程序访问缓存时有60%的时间我得到缓存未命中。另一方面,缓存未命中指令比率仅为0.6%。

我不知道该怎么办。我应该针对哪个比例进行优化?

1 个答案:

答案 0 :(得分:2)

他们最终都是误导,但是以不同的方式。

错过命中很有趣,但是你可以通过在处理未命中时进行大量算术来“浸透”一些失误。错过#instructions会告诉你一些关于这一点的事情,因为非常少的未命中/指示暗示你就是这种情况。这并不意味着你实际上是这样,例如,如果未命中的下一个负载的地址是通过长计算计算的,该计算本身取决于先前的未命中,那么它全部变为序列化并且未命中/指令变得有点误导。即便如此,如果它足够低,那么总时间主要取决于算术,因此未命中不会是一个大问题。

它不一定要优化,因为你可以通过做无用的算术工作来作弊。或者,更合理的是,做一个折衷,花费更多(有用的)算术来减少一些失误,这听起来不错,除了你可以走得太远。显然,如果它开始花费更多的实际时间(或者一般情况下它开始在你真正关心的任何事情上表现更差),你改进一些相当人为的指标并不重要(除非那真的是你关心的,你可能在合成基准中)。

错过/引用显然会告诉您有关访问模式的信息,但是执行大量缓存命中内存引用并不是良好代码的指示:可能只有很多不必要的内存引用。或者换句话说,如果数据只需要一次,那么再次触摸它(即使不产生遗漏)仍然是一种浪费。这真的取决于问题。例如,如果你只是总结一个数组,那么从这个指标的角度来看,将累加器放在内存中看起来真的很好,但这显然是一件非常糟糕的事情。

所以,

  

我应该针对哪个比例进行优化?

两者都没有,除非你想要纯粹合成的东西。使用它们来了解代码的执行方式,然后优化已用时间(或功率或其他任何内容,取决于您的目标)。这些“非常好”的元素可能与它们“糟糕”一样具有线索,所以也许这应该被称为低和高。