最高效的缓存替换算法


12

维基百科列出了11种缓存替换算法。假设我对我将要开发的应用程序几乎一无所知,那么应该使用什么作为“默认”缓存替换算法?

如果我从操作系统课程中正确回忆起,LRU是最好的通用缓存替换算法。但也许我弄错了。

另外,这是一个学术问题,因为通常来说,主内存便宜又丰富,我真的不需要担心缓存大小。


1
预取与您的应用程序相关吗?如果是这样,则在选择算法时必须同时考虑预取和保留策略。
rwong 2011年

您将需要获取代表您想要的应用程序域的示例跟踪(数据访问模式列表)。您也许可以从学术研究中找到公开可用的测试集。然后,您可以实现每种算法,进行仿真并报告您的发现。如果失败,请使用LRU进行少量随机更换。
rwong 2011年

1
如果你“几乎一无所知的应用程序”,那么它早去想“高效”的缓存替换算法。
Anon

主存储器可能很便宜,但是如果性能是一个重要问题,则访问效率将很重要。我认为您无法选择缓存替换策略-除非您是新计算机的首席架构师。我们其余的人都能得到市场提供的一切。如果需要快速处理,则需要组织计算和数据结构以有效利用内存层次结构。
欧米茄Centauri

1
@Omega Centauri您仅想到CPU缓存,但还有更多。操作系统缓存使用过的文件和目录,数据库缓存其数据,几乎每个应用程序都进行很多缓存(例如,已计算的结果)。
maaartinus 2011年

Answers:


15

我猜最好的答案是,这取决于。以我的经验,选择缓存算法有很多因素。

要考虑的因素

  1. 读/写平衡。(读与写访问的百分比)
  2. 缓存量。
  3. 高速缓存后面的媒体类型。(它们是慢速SATA驱动器还是快速的SSD驱动器?)
  4. 热门与未成年人。(多久重写或重新阅读一次?)
  5. 平均访问大小(用于选择页面大小)
  6. 读写有多昂贵。

一旦考虑了所有不同因素,就需要找到一种能够最好地处理该问题的缓存算法。例如,假设您有一个应用程序,其中包含大量写入,一些重写,读取最近写入的数据以及某种旋转介质。在这种情况下,您将需要一种混合缓存算法。要处理写入数据,您可能需要诸如写入明智顺序(WOW)和针对已从磁盘读取的数据的LRU算法之类的东西。这样做的原因是磁盘访问非常昂贵,并且WOW算法将使其更有效地写出数据,而LRU会将经常访问的数据始终保留在缓存中。

假设您有访问时间非常快的SSD磁盘,由于磁盘访问相对便宜,因此您可能希望将选择转向LRU算法。

因此,我真正想说的是,没有“最佳”答案。最好的答案是知道适用于您的因素并选择最能解决这些问题的算法。

如何为您找到算法

分析您的系统。这通常涉及添加代码以保留有关内存访问的统计信息。通过分析,您可以查看哪些因素对您最重要。

过去,我添加了代码来跟踪一段时间内的所有内存访问。然后,我寻找模式。我寻找重新读取,重新写入,顺序访问,随机访问等。

一旦确定了重要的事物,就需要查看所有不同类型的缓存算法,以了解哪个处理最佳。


重大分解因素。但是由于我知道应用程序领域和因素,因此我不确定如何应用它们。
ashes999 2011年

@ashes:有一种古老的工程技术:以不同的方式构建一些,并衡量哪种方法最有效。
Donal Fellows

当我听到“缓存”时,我想到的是内存和CPU寄存器之间的存储。在这里,您谈论的是磁盘缓存,它是内存和一个或多个I / O设备之间的一层。
欧米茄Centauri

@ barrem23如果您正在进行分布式编程,则还需要考虑“缓存与要缓存的后端存储之间的距离”。没关系,如果存储空间为15毫秒,如果您有SSD或旋转的锈迹作为大型,稳定的存储空间,那么无论如何总会产生最少30毫秒的往返行程。
Vatine 2013年

9

假设您几乎对将要开发的应用程序一无所知,那么在实际选择和实现缓存系统之前,您应该对它了解更多。换句话说,没有默认实现:有些实现对某些目的有用,而对其他目的则完全不利

例如,仅采用两种实现方式:最近最少使用和经常最少使用。如何决定先使用哪个?

  • 当您确定用户将更频繁地访问最新项目并且永远不会或很少返回旧项目时,LRU很好。一个示例:电子邮件客户端的一般用法。在大多数情况下,用户一直在访问最新的邮件。他们阅读,推迟,在几分钟,几小时或几天后返回,等等。他们可以发现自己正在搜索两年前收到的邮件,但这种情况发生的频率比访问最近两个小时收到的邮件要少。

  • 另一方面,在用户将比其他项目更频繁地访问某些项目的情况下,LRU没有意义。例如:我经常听自己喜欢的音乐,并且碰巧有400首歌曲,我每周至少听一次相同的五首歌曲,而我每年最多只能听一次我也不喜欢的100首歌曲许多。在这种情况下,LFU更合适。

通过仅采用两种实现,您会发现当您不想考虑哪一种更好或者没有足够的有关应用程序的信息时,就可以使用“默认”算法。很好,就像询问默认情况下一样,当您不知道微积分的结果时,必须对两个数字进行加,减,乘或除运算。


好的,那我该如何选择算法呢?浏览维基百科的列表,看看最合适的是什么?
ashes999 2011年

@ ashes999:完全是!首先,您了解有关应用程序需求的更多信息,然后分析不同缓存算法的优缺点,最后选择更合适的缓存算法。
Arseni Mourzenko 2011年

3

为什么将您的选择仅限制在Wikipedia上?如果您可以访问ACM数字图书馆等研究数据库,则可以找到更多的算法。也要注意搞乱专利。例如,ARC是一种很好的算法,但不幸的是它已申请了专利。


2

您可能花费大量时间为“最佳”算法苦恼,或者您可以实施一个简单的算法并继续使用系统的其余部分。如果你有什么可测试担心算法。

过早的优化...


0

没有完美的缓存算法-您总是可以找到一个表现很差的案例。

因此,重要的是要知道要缓存的问题以确定最不严重的问题。

另外,您应该考虑需要缓存多长时间以及可以缓存多长时间...

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.