【问题标题】:LRU Cache design in C with of limited sizeC语言中的LRU缓存设计,大小有限
【发布时间】:2011-03-12 16:41:00
【问题描述】:

我现在正在开发内存非常小的移动平台上的软件。在 I/O 瓶颈函数中,我需要使用 seek 操作从 img 文件中读取一些字节(您可以假设 seek 比直接从 memmry 中读取慢约 10 倍)。在我的测试中,这个函数被调用了 7480325 次,从 bytes_offset 6800 到 130000 读取字节,所以每个字节平均读取 100 次(有些字节读取 3~4 次,有些超过 1000 次)。

以下是我的统计数据。

bytes offset 6800 ~ 6900: 170884 times
bytes offset 6900 ~ 7000: 220944 times
bytes offset 7000 ~ 7100: 24216 times
bytes offset 7100 ~ 7200: 9576 times
bytes offset 7200 ~ 7300: 14813 times
bytes offset 7300 ~ 7400: 22109 times
bytes offset 7400 ~ 7500: 19748 times
bytes offset 7500 ~ 7600: 43110 times
bytes offset 7600 ~ 7700: 157976 times
...
bytes offset 121200 ~ 121300: 1514 times
bytes offset 121300 ~ 121400: 802 times
bytes offset 121400 ~ 121500: 606 times
bytes offset 121500 ~ 121600: 444 times
bytes offset 121600 ~ 121700: 398 times

max_bytes_offset 121703
min_bytes_offset 6848

然后我想使用 LRU 模式构建一个缓存,以使 I/O 性能更好。在其他一些问题中,我发现哈希表 + 双向链表是一个好方法。但是如何建立一个结构以最好的方式改善我的问题呢?我计划构建1300个桶,每个桶都有一个最大大小为10的双向链表。那么它需要的总内存大约是13KB。实现和维护都很简单,但我认为效率不是最好的。

在我的统计中,某些字节偏移间隔的命中率更高,而某些间隔的命中率更低。如何构建一个结构来调整我的统计数据?

而且当我搜索一个key时,我需要遍历整个列表,大小为10。有没有其他搜索效率更高的方法?

在某些移动平台中,更多内存可用于缓存,而其他平台则允许更少。除了更改存储桶的大小之外,如何使我的缓存适应允许的内存更改?

好像caf的方法比较好。使用大的双向链表和大的哈希表将键映射到节点条目更有意义,并且可以更多地利用 LRU。但是设计哈希函数正在成为一个难题。

等待你的建议,谢谢~

【问题讨论】:

  • 是否存在预期的参考位置偏差?有这方面的统计数据吗?
  • 你是说两个读字节的关系?您可以假设它们之间没有关系,因为 img 文件存储了一些树结构。
  • 我搞错了-_-。有一个预期的参考地点,我正在研究它的统计数据

标签: c caching mobile-phones lru


【解决方案1】:

如果您在每个存储桶中最多只能有 10 个条目,那么最好不要使用双向链表,而只需将每个存储桶设为一个循环数组(即只有 10 个条目和一个“列表顶部”索引)。

您最好放弃 10 路集合关联设计并使用直接映射缓存(您有一个更大的哈希表,每个桶只存储一个条目)。集合关联设计在硬件方面很好,您可以使用专用硬件并行进行 n 路比较,但在软件方面则不然(除非您有一个可以利用的向量单元)。

适应您的统计数据的一种方法是设计您的哈希函数,以便将不同大小的地址范围映射到每个存储桶上,从而使每个存储桶获得大致相等的访问频率。

改变哈希表的大小是另一种明显的调整缓存大小的方法。

【讨论】:

  • 您的意思是使用哈希表来指示双向链表中的元素?这听起来不错,但设计我的哈希函数并不容易。我会尽力。而且我只能在软件中实现缓存:-(
猜你喜欢
  • 2011-01-31
  • 1970-01-01
  • 1970-01-01
  • 2011-03-02
  • 1970-01-01
  • 2018-09-30
  • 1970-01-01
  • 2012-03-13
  • 2021-03-05
相关资源
最近更新 更多