如何在估算性能时考虑缓存未命中?

时间:2015-08-21 16:55:58

标签: algorithm performance caching

通常,性能以O()的数量级给出:O(Magnitude)+K其中K通常被忽略,因为它主要适用于较小的N

但是我越来越多地看到性能主要受基础数据大小的影响,但这不是算法复杂性的一部分

假设algorithm AO(logN)但使用O(N)空格且algorithm BO(N)但使用O(logN)过去属于algorithm A {1}}更快。现在,多层缓存中的缓存未命中,algorithm B对于大数字可能会更快,如果K

更小,则可能会更小

问题是你如何表达这个?

2 个答案:

答案 0 :(得分:2)

缓存未命中在大O表示法中没有考虑,因为它们是常数因素。

即使你悲观地假设每个数组搜索都将是一个缓存未命中,并且让我们说缓存未命中需要100个周期(这个时间是恒定的,因为我们假设是随机存取存储器),而不是迭代长度n的数组将花费100*n个周期来缓存未命中(+循环和控制的开销),一般而言,它仍为O(n)

大O经常使用的一个原因是因为它与平台无关(好吧,至少在谈到RAM机器时)。如果我们考虑缓存未命中,那么每个平台的结果都会有所不同。

如果您正在寻找一种考虑常数的理论符号 - 您正在寻找tilde notation

另外,这就是为什么"大O符号"对于大规模或时间关键的系统来说,这些系统很少用,而且这些系统经常被发现以找到开发人员会在本地改进的瓶颈,因此如果您正在寻找真正的性能 - 请根据经验进行,并且不要做任何事情。理解为理论符号。

答案 1 :(得分:1)

嗯,O(N)命名法的使用抽象出一些重要的细节,这些细节通常只有在N接近无穷大时才是微不足道的。这些细节可能并且通常是N值小于无穷大的最重要因素。为了帮助解释,考虑如果一个术语被列为O(N ^ x),它只是指定N的最重要因子。实际上,性能可以表征为:

aN ^ x + bN ^(x-1)+ cN ^(x-2)+ ... + K

因此,当N接近无穷大时,主导项变为N ^ x,但显然在N值小于无穷大时,主导项可能是较小项之一。查看您的示例,您将提供两种算法。我们称算法A是提供O(N)性能的算法,而提供O(logN)性能的算法我们称之为算法B.实际上,这两种算法的性能特征如下:

表现A = aN + b(log N)+ c

表现B = x(log N)+ y

如果您的常数值是a = 0.001和x = 99,999,您可以看到A如何提供比B更好的性能。此外,您提到一种算法会增加缓存未命中的可能性,并且可能性取决于大小的数据。您需要根据数据大小确定缓存未命中的可能性,并在计算整个算法的O性能时将其用作因子。例如:

如果高速缓存未命中的成本是CM(我们假设它是常数),那么对于算法A,整体高速缓存性能是F(N) CM。如果该高速缓存性能是算法A的主导循环(O(log N)部分)中的因素,则算法A的实际性能特征是O(F(N)(log N))。对于算法B,整体缓存性能将是F(log N)* CM。如果在算法B的主导循环期间出现高速缓存未命中,则算法B的实际性能为O(F(log N)* N)。只要您可以确定F(),就可以比较算法A和B.