1

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

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

  1. 我可以考虑一个生命周期排序列表,pair<size_t lifeTime, myStructType v>加上一个映射到 o(1) 从它的键访问列表中所需对象的索引,我可以使用 shm 和 mmap 来存储所有内容,并使用一个锁来管理访问(cf在这里)。
  2. 我可以使用为 LRU 配置的 redis 服务器,并将我的数据结构重新设计为 redis 键/值和键/列表对。
  3. 我可以使用为 LRU 配置的 redis 服务器,并将我的数据结构 (myStructType) 序列化为使用 redis 管理的简单键/值。

当然可能还有其他解决方案。您将如何做到这一点,或者更好的是,您如何成功地做到这一点,同时牢记高性能?

另外,我想避免像 Boost 这样的重度依赖。

4

1 回答 1

2

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

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

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

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

一个快速的胜利是不更新最后使用元素的 LRU 时间。它已经是最新的了,再更新也无济于事。这当然只有在您经常再次快速使用该元素时才会产生效果,但是(如上所述)否则您只会使用随机驱逐。

于 2013-08-08T07:50:25.480 回答