zoukankan      html  css  js  c++  java
  • [转]LRU的改进算法LIRS

    LRU(Least Recent Used)是我们在cache替换算法中最普遍使用的算法,在缓存块已满,而需要缓存新的数据块的时候,这时需要从缓存中找到一个“没有价值”的块用新的数据块去替换它。

    LRU的特点是简洁高效,但是缺点是LRU的缺点是不能对weak locality的数据进行缓存。

    a. 如果stack size有1000个块,而一个文件是1001个块的大小,而且每次访问都是从头到尾的访问。则LRU的性能非常差,几乎没有任何缓存。

    b. 假设我们要邀请学习好的同学到一个容纳10人的会议室开会。如果是LRU算法的话,会邀请90分以上或者80分以上的人,,但是如果没有80分以上的同学则一个都不邀请,而会议室也就白白浪费了,对于LIRS,邀请成绩前在10名的同学到会议室。这里会议室为我们的stack ,这样我们的会议室也就是stack至少不会浪费。

    所以我们这里边的问题就是如何把一些weak locality的数据也能够缓存起来,使我们的cache得到充分的使用?

    2. 两个概念

    Reuse: 一个块被使用之后,再次被使用

    Recency:一个块被访问后,和上一次访问之间的距离。

    LIRS的基本思想是对访问的数据块进行分类,一部分为hot数据块,一部分为cold数据块。对于hot数据块我们可以分配90%以上的cache给它们。而对于cold数据块给它们分配10%。 从LIRS算法的描述来看,可以理解为两个LRU队列的组合,利用cold缓冲区来保护Hot缓冲区,提高了进入hot缓冲区的门槛,阻止hot缓冲区频繁地变化。

    LIRS算法实现: 首先说明LRU算法的实现。 采用带表头的单链表来存储数据节点,head指针指向表头,tail指针指向链表最后一个节点。数据节点则记录了每个缓存块的ID,加载状态,数据指针,next指针。另有unUsedSize变量存放未分配的缓存块数量。 当用户访问命中时,将对应的数据节点移到队列尾部。当用户访问未命中时,若能分配新数据节点,则分配,否则从表头摘下一个数据节点,并卸载数据。更新得到的数据节点的信息,并加到队列尾部。 最后,为了避免在查找数据节点时遍历整个链表,增加了Dictionary的字典,利用其hash查找功能提高查找效率。 再说明LIRS算法的实现。 为了简化实现,将算法实现为多个逻辑LRU队列(可实现多级缓冲区),在物理实现上,仍采用带表头的单链表来存储数据节点。对于N级缓冲区的实现(原始的LIRS算法为2级),使用unUsedSize[N]数组存放每个缓冲区的未分配数量,使用head[N+1]存放缓冲区的头尾指针。这样head[0]、head[1]指示了第0块缓冲区的头尾,依次类推,head[N-1]、head[N]指示了第N-1块缓冲区的头尾。0号缓冲区是cold的缓冲区,N-1号则是最hot的。由于使用了多级缓冲区,数据节点也需要增加一个选择器selector,用于指示该节点属于哪个缓冲区。 当用户访问未命中,分配新节点时,先检查N-1号缓冲区是否能分配新节点,若不能则依次向前检查。若分配了新节点,则直接加入相应缓冲区的尾部,否则就从0级缓冲区头部摘下一个节点来,更新节点信息后加入0级缓冲区尾部。 当用户访问命中时,则将x级的节点提升到x+1级,并加到缓冲区尾部,x+1级的头部节点,则被移到x级缓冲区的尾部 同样的,增加了Dictionary字典,提高查找节点的效率。

    From:http://nullget.sourceforge.net/?q=node/609

  • 相关阅读:
    技术周刊 · 耿耿星河欲曙天 | SpaceX 上的前端架构;跨平台新选择;开源世界的新“大门”;用户推荐算法的敲门砖……
    说说SVG的feTurbulence滤镜
    机器学习进阶
    小程序与动画的故事
    技术周刊 · 迢迢山径峻 | Web 开发成长图谱;下一代前端构建技术;AI 应用下支离破碎的真实;不懂产品不会开发;虚拟货币是新时代的黄金
    从中断机制看 React Fiber 技术
    三分钟了解数字人民币
    凹凸技术揭秘:如何服务 toG 项目——数字人民币项目前端总结
    使用 Phaser3+Matter.js 实现“合成大西瓜”游戏
    痞子衡嵌入式:快速定位i.MXRT600板级设计ISP[2:0]启动模式引脚上电时序问题的方法
  • 原文地址:https://www.cnblogs.com/shelly/p/2791426.html
Copyright © 2011-2022 走看看