如何LRU缓存由C ++ STL重型结构组成的众多对象?

时间:2013-08-07 16:49:59

标签: c++ caching stl redis lru

我有大量的C ++ / STL数据结构(myStructType),带有叠加的列表和映射。我有很多这种类型的对象我想用一个键来LRU缓存。我可以在需要时从磁盘重新加载对象。此外,它必须在运行在BSD平台上的多处理高性能应用程序中共享。

我可以看到几种解决方案:

  1. 我可以考虑一个pair<size_t lifeTime, myStructType v>的生命时间排序列表加上一个映射到o(1)从其键中访问列表中所需对象的索引,我可以使用shm和mmap来存储所有内容,以及用于管理访问权限的锁(cf here)。
  2. 我可以使用为LRU配置的redis服务器,并将我的数据结构重新设计为redis键/值和键/列对。
  3. 我可以使用为LRU配置的redis服务器,并序列化我的数据结构(myStructType)以使用redis管理一个简单的键/值。
  4. 当然可能还有其他解决方案。您如何做到这一点,或者更好,您如何成功地做到这一点,牢记高绩效?

    此外,我想避免像Boost那样严重依赖。

1 个答案:

答案 0 :(得分:2)

我最近实际构建了缓存(不仅仅是LRU)。

选项2和3很可能不比从磁盘重新读取快。这根本就没有缓存。此外,这将是一个比Boost更重的依赖。

选项1可能具有挑战性。例如,你建议“锁定”。这将是一个非常竞争的锁,因为它必须保护每一个生命周期更新,以及所有LRU操作。由于您的对象已经很重,因此每个对象具有唯一锁定值可能是值得的。这个解决方案有中间变体,其中有多个锁,但每个锁也有多个对象。 (你仍然需要一把钥匙来保护整个地图,但这只是为了替换)

您还可以考虑是否真的需要严格的LRU。该策略假设对象重用的可能性随着时间的推移而降低。如果这不是真的,随机替换也同样好。您也可以考虑一次驱逐多个元素。其中一个挑战是当一个元素需要删除时,所有线程都是这样,但如果一个线程删除它就足够了。这就是批量删除有帮助的原因:如果一个线程试图锁定批量删除并且它失败了,它可以继续假设缓存很快就会有空闲空间。

一个简单的胜利是不更新上次使用的元素的LRU时间。它已经是最新的,任何新的都无济于事。如果你经常再次快速使用那个元素,这当然只有效果,但是(如上所述)否则你只是使用随机驱逐。