CMU15/445 2023 Spring-project1 LRU-K 替换策略

在写个demo之前,专门学习了LRU:【LeetCode刷题】146. LRU 缓存-CSDN博客

使用哈希表 + 双向链表可以满足删除/增加的时间复杂度为O(1)。

在通读完15/445这块的说明之后,发现和LRU还是有些差别的。

官方文档中对LRU-K的解释是:LRU-K算法根据所谓的“后向k距离”来确定替换哪个缓存帧。后向k距离是指当前时间戳与第k次访问之间的时间差。如果某个缓存帧的历史访问次数少于k次,则其后向k距离被视为正无穷当有多个缓存帧的后向k距离都是正无穷时,LRU-K算法会选择替换具有最早总体时间戳的缓存帧。换句话说,它会替换最近访问时间最早的缓存帧,从而使得系统更可能淘汰不常用的数据,而保留最常用的数据。

解释一下:之前学习的LRU算法是替换/最近最少使用的数据,在具体实现上采用的是哈希+双向链表的形式,将最近使用的数据放在双向链表表头,最少使用的放在尾部。

这里的LRU-K算法是以当前节点位基准,往前计数到第k个位置,将该位置的数据剔除;如果没有第k的位置,则后向距离视为正无穷(2147483647);当有多个缓存帧的后向k距离都是正无穷时,LRU-K算法会选择替换具有最早总体时间戳的缓存帧(即替换最先加进来的数据)。

15/445中的代码这里有两个类:LRUKNode类和LRUKReplacer类。

1 LRUKNode类

LRUKNode中有一些属性:

  [[maybe_unused]] std::list<size_t> history_;
  [[maybe_unused]] size_t k_;
  [[maybe_unused]] frame_id_t fid_;
  [[maybe_unused]] bool is_evictable_{false};

(1)history就是存放数据的节点,而C++中的list底层是双向链表,可以满足前插和删除操作;

(2)k_就是参数k;

(3)fid_是帧id,类型是using frame_id_t = int32_t;    // frame id type;

(4)是否要剔除该节点,默认不剔除。

对照着LRUKReplacer的函数,给LRUKNode添加几个函数:

(1)构造函数肯定是要的;

(2)计算k距离的函数;(遍历到第k个相减即可,注意没有第k个情况时要返回无穷大)

(3)记录LRUKNode对象的访问历史函数;

开始可能就能想到这几个,增量式开发,后面写着写着需要哪些再添加。

2 LRUKReplacer类

对代码中的LRUKReplacer类各个函数一定要理解清楚。

(1)Size函数是最好实现的(::>_<::);

(2)Remove函数的实现思路:先查找,如果数据存在,再判断该数据是否是要被剔除的,如果是则删除;

(3)SetEvictable函数是指定帧是否可被替换的状态。这个函数还控制替换器的大小;

(4)RecordAccess是添加数据的,数据存在更新换时间戳;数据不存在则添加新的数据;

(5)Evict是最难的。【查找具有最大后向k距离的帧,并将其替换。只有被标记为可被替换的帧才是替换的候选对象。成功替换后,应该减少替换器的大小并移除帧的访问历史。】

LRU-K算法根据所谓的“后向k距离”来确定替换哪个缓存帧。后向k距离是指当前时间戳与第k次访问之间的时间差。如果某个缓存帧的历史访问次数少于k次,则其后向k距离被视为正无穷当有多个缓存帧的后向k距离都是正无穷时,LRU-K算法会选择替换具有最早总体时间戳的缓存帧。换句话说,它会替换最近访问时间最早的缓存帧,从而使得系统更可能淘汰不常用的数据,而保留最常用的数据。

  [[maybe_unused]] std::unordered_map<frame_id_t, LRUKNode> node_store_;
  [[maybe_unused]] size_t current_timestamp_{0};
  [[maybe_unused]] size_t curr_size_{0};
  [[maybe_unused]] size_t replacer_size_;
  [[maybe_unused]] size_t k_;
  [[maybe_unused]] std::mutex latch_;

(6)这里也用到了哈希+list,符合前面LRU的思路,只是后面在测试的时候,发现unordered_map的value一直有问题,网上查了一下,大家都是用的指针形式,后面又使用了智能指针;

(7)std::mutex不允许拷贝构造,也不允许 move 拷贝,使用智能指针的形式;

c++ - 在 C++ 中使用用户定义的类型作为映射值 - IT工具网 (coder.work)

(8)宏的学习:这个宏的作用是确保 LRUKReplacer 类不能被拷贝构造、拷贝赋值、移动构造和移动赋值;

// 这个宏的作用是确保 LRUKReplacer 类不能被拷贝构造、拷贝赋值、移动构造和移动赋值。
DISALLOW_COPY_AND_MOVE(LRUKReplacer);

#define DISALLOW_COPY_AND_MOVE(cname) \
  DISALLOW_COPY(cname);               \
  DISALLOW_MOVE(cname);

// Macros to disable copying and moving
#define DISALLOW_COPY(cname)                                    \
  cname(const cname &) = delete;                   /* NOLINT */ \
  auto operator=(const cname &)->cname & = delete; /* NOLINT */

#define DISALLOW_MOVE(cname)                               \
  cname(cname &&) = delete;                   /* NOLINT */ \
  auto operator=(cname &&)->cname & = delete; /* NOLINT */

(9)还学习了一个之前没注意到的小知识:成员列表初始化属性的时候,要按照属性在类中出现的顺序初始化;

(10)删掉测试代码的DISABLED_

3 结果

这里只实现了LRUKdemo,所以得分是25分,看通过的case,LRUKReplacerTest是通过的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/522166.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Spring boot框架Rouyi Cloud入门之token

&#x1f339;作者主页&#xff1a;青花锁 &#x1f339;简介&#xff1a;Java领域优质创作者&#x1f3c6;、Java微服务架构公号作者&#x1f604; &#x1f339;简历模板、学习资料、面试题库、技术互助 &#x1f339;文末获取联系方式 &#x1f4dd; 往期热门专栏回顾 专栏…

【Gluten】Spark 的向量化执行引擎框架 Gluten

Gluten 项目主要用于“粘合” Apache Spark 和作为 Backend 的 Native Vectorized Engine。Backend 的选项有很多&#xff0c;目前在 Gluten 项目中已经明确开始支持的有 Velox、Clickhouse 和 Apache Arrow。通过使用Native backend 执行计算&#xff0c;加速 Spark 执行速度&…

超市商品管理系统的设计与实现(全套资料)

一、系统架构 前端&#xff1a;vue | view-design 后端&#xff1a;springboot | mybatis-plus 环境&#xff1a;jdk17 | mysql8 | maven | nodejs | redis 二、代码及数据库 三、功能介绍 01. web端-首页 02. web端-超市概况 03. web端-超市区域 04. …

【Web】纯萌新的BUUCTF刷题日记Day1

目录 [RoarCTF 2019]Easy Java [网鼎杯 2018]Fakebook [CISCN2019 华北赛区 Day2 Web1]Hack World [BJDCTF2020]The mystery of ip [网鼎杯 2020 朱雀组]phpweb [BSidesCF 2020]Had a bad day [BJDCTF2020]ZJCTF&#xff0c;不过如此 [BUUCTF 2018]Online Tool [GXYCTF…

并发 ---- 多线程原理及底层实现

并发现象遍布日常生活&#xff0c;我们时常接触&#xff1a;我们可以边走路边说话&#xff1b;或者&#xff0c;左右手同时做出不一样的动作。在计算机应用程序中也有很好的例子&#xff1a; 浏览器 - 浏览器可以同时下载任意数量的文件和打开多个网页&#xff0c;下载时仍允许…

观测线程的工具——jconsole

joconsole的简单使用 joncole位置在jdk/bin路径中&#xff0c;在进入路径后可以查找到jconsole.exe的应用程序。如图&#xff1a; 双击创建jconsole进程&#xff0c;可以在里面选择所要观测的java文件。 以我的代码为例&#xff1a; class MyThread extends Thread {Overrid…

用户侧终端表计--预付费电表/费控/时间控制/负载控制/远程充值/远程抄表/分时计量/定量电能表/多回路预付费电表

预付费电表&#xff08;先付费后用电&#xff09;又叫做定量电能表&#xff0c;除了具有普通电能表的计量功能外&#xff0c;特别的是用户先买电&#xff0c;买电后才能用电&#xff0c;若用完电后用户不继续买电&#xff0c;则自动切断电源停止供电。 安科瑞薛瑶瑶1870170908…

Spark编程基础

一、RDD入门 1.RDD是什么&#xff1f; RDD是一个容错的、只读的、可进行并行操作的数据结构&#xff0c;是一个分布在集群各个节点中的存放元素的集合&#xff0c;即弹性分布式数据集。 2.RDD的三种创建方式 第一种是将程序中已存在的集合&#xff08;如集合、列表、数组&a…

【JavaSE零基础】00-基础语法(1-12章)

1 第一章 Java开发环境搭建 1.1 章节目标与知识框架 1.1.1 章节目标 掌握Java的开发环境搭建&#xff0c;会编写HelloWorld程序&#xff0c;并能够准确的进行编译和运行&#xff1b;理解path和classpath环境变量并可以自行配置。 1.1.2 知识框架 1.2 Java语言概述(了解) J…

Uniapp/HTML5 上传文件到腾讯云Cos图片存储(Demo)

Uniapp引入方式 npm install cos-js-sdk-v5 HTML引入方式 <script type"text/javascript" src"js/cos-js-sdk-v5.min.js"></script> 在腾讯官网中找到cosJs放到本地项目中引入在项目中util工具类目录下封装一个upload.js用于公共上传Js impo…

操作系统②——内存管理

1. 栈、堆 1.1 程序的内存分配 栈区&#xff08;stack&#xff09;&#xff1a;由编译器自动分配释放 &#xff0c;存放函数的参数值&#xff0c;局部变量的值等。其操作方式类似于数据结构中的栈。堆区&#xff08;heap&#xff09;&#xff1a;一般由程序员分配释放&#x…

C++:stack类和queue类

stack的介绍和使用 1. stack 是一种容器适配器&#xff0c;专门用在具有后进先出操作的上下文环境中&#xff0c;其删除只能从容器的一端进行元素的插入与提取操作。 2. stack 是作为容器适配器被实现的&#xff0c;容器适配器即是对特定类封装作为其底层的容器&#xff0c;并…

H265码率控制(一)之HM代码R-λ model介绍

前言 在HM中R-λ的码率控制引入是在k0103提案中开始引入的&#xff0c;代码是HM-8.0以后的版本出现的&#xff0c;后面经过多个提案不断的修改&#xff0c;如M0257提案&#xff0c;M0036提案等&#xff1b;笔者建议研究HM代码的R-λ码率控制从HM10.0版本开始这个版本的R-λ已经…

1.基础乐理-唱名与记住唱名的方法

首先有 0、1、2、3、4、5、6、7&#xff0c;这八个数字 在音乐中要用笔来记录音乐就要用到 0、1、2、3、4、5、6、7&#xff0c;这八个数字&#xff0c;如果我们要唱出来 或 说出来&#xff0c;只要用嘴巴说出来就不是用 0、1、2、3、4、5、6、7&#xff0c;这八个数字了&…

雄安新区:创新引领,未来产业的摇篮

雄安新区&#xff1a;创新引领&#xff0c;未来产业的摇篮 随着雄安新区的建设不断推进&#xff0c;这座未来之城正逐渐成为创新的高地和创业的热土。在这片充满希望的土地上&#xff0c;全过程创新生态链正在形成&#xff0c;为未来产业的发展提供了坚实的基础。 创新高地&a…

机器学习(五) -- 监督学习(3) -- 朴素贝叶斯

系列文章目录及链接 目录 前言 一、朴素贝叶斯通俗理解及定义 二、原理理解及公式 1、概率基础 2、贝叶斯公式 3、拉普拉斯平滑系数 三、**算法实现 四、接口实现 1、新闻数据集介绍 2、API 3、流程 3.1、获取数据 3.2、数据预处理 3.3、特征工程 3.4、朴素贝叶…

java代码混淆,保护源码的重要性

Java代码混淆是一种重要的安全措施&#xff0c;用于保护Java应用程序的源代码免受恶意攻击和逆向工程的影响。下面是关于Java代码混淆以及保护源码重要性的详细说明&#xff1a; 1. 什么是Java代码混淆&#xff1f; Java代码混淆是指通过对Java代码进行一系列的转换和优化&am…

SD卡误删怎么恢复?5个恢复方法助你找回数据!

“我刚刚在清理sd卡时突然发现sd卡里的部分文件误删了&#xff0c;大家有什么方法可以恢复sd卡重要文件吗&#xff1f;” SD卡&#xff0c;作为一种常见的存储设备&#xff0c;经常用于手机、相机等电子设备中&#xff0c;存储着大量的数据。然而&#xff0c;误删操作往往会导致…

容器和K8s常见概念

【容器】 1、Open Container Initiative&#xff08;OCI&#xff09;&#xff1a;制定和推动容器格式和运行时的开放标准。容器运行时需要遵循此标准。主要的产出物包括&#xff1a; OCI Image Specification: 定义容器镜像格式的规范&#xff0c;统一描述容器镜像的内容和结…

CSS - 你能尽量多的说出两边固定,中间自适应的三栏布局如何做吗

难度级别:初级及以上 提问概率:65% 前端面试中,布局类题目被问道的频次会非常高,这道题,我们通过以下四种方式来实现。 目录 1 使用flex布局 2 使用绝对定位和margin配合的方式