CMU15445-project1-满分收获总结


在这里插入图片描述

在这里插入图片描述

TASK #0 gradescope
0.0 关于线上测试的天坑

在gradescope上测试代码时,没有通过的案例如果显示的是超时,那不一定是因为死锁或者死循环!

  1. 我没有写线程安全的代码,显示的是超时
  2. 我代码有的部分会造成内存泄漏,显示的还是超时
  3. 死锁或者replacer复杂度太高确实有可能造成超时
TASK #1 - LRU REPLACEMENT POLICY
1.1线程安全

要求了线程安全但又没有说具体怎么做,以至于在最后才回来考虑上锁的问题。

其实很简单,在头文件内声明一个锁。在实现的每个函数开头上锁,结尾释放就行。

// 头文件
#include<mutex>
// 声明
std::mutex lock_;
//上锁(请求锁),释放锁
lock_.lock();
lock_.unlock();

注意事项:
1.每个return之前都要记得释放锁
2.关于死锁,如果都是开头上锁结尾解锁,根本不会有产生死锁的条件(请求并保持)。
3.如果在一个函数里调用了另一个使用lock的函数,百分百会卡死,因为这个函数的lock还未释放,调用的函数就会一直等待lock。解决办法:在函数调用前释放锁,调用后申请锁。(但这个project可其实以避免这种调用关系)

1.2 upin 和 pin 如何理解

pin():就理解成有人正在使用这个页面,不能用来作为牺牲了,故需要删除当前frame_id(而不是放在末尾)
unpin():lru_relpacer不需要考虑什么时候需要unpin,直接理解成当前frame_id可以作为牺牲id,装入队列就行。

1.3 优化搜索效率

使用STL自带的unsord_map()作为hash表,keyframe_idvaluelist内对应元素的指针(迭代器),这样对frame_id对应的元素的操作只需要O(1)级别复杂度。
对应的leetcode题,代码相似度很高

//初始化
std::list<frame_id_t> page_list_;
std::unordered_map<frame_id_t, std::list<frame_id_t>::iterator> frame_table_;

// 使用示例
auto it = frame_table_.find(frame_id);
if (it != frame_table_.end()) {  // exist
  page_list_.erase(it->second);
  frame_table_.erase(it);
}
TASK #2 - BUFFER POOL MANAGER INSTANCE
2.1 frame_id和page_id的关系
  • 每一个BPLI(BUFFER POOL MANAGER INSTANCE)都会被分配一个固定的pool_size_,根据pool_size_ 新建的pages_数组实际上就是BPLI用来存放页面的盒子。
  • 直观上来看,frame_id就是是pages_数组的下标,而page_id指的放入盒子(数组)的page号。
  • 所以replacer管理的是frame_id的分配,BPLI 的工作就是负责分配frame_id(实则是分配盒子)给pages
2.2 天坑:DeletePgImp() 的返回值问题

这个坑卡了我一下午的时间debug,就一个返回值让我从62分跳到了96分。
在这里插入图片描述
按道理找不到页面应该返回false,这里却要求的是true。虽然也的确是审题不当,但这个着实把我坑惨了。

2.3 UnpinPgImp() 注意事项,dirty()测试跑不通

这个函数没有太多注解,所以有的地方都是靠上传测试摸索出来的,感觉实在没必要。
1.对于pin_count_大于1的情况,是减一,而不是清零。
2.不需要对脏页面进行写回磁盘,只需要把脏标记在对应page上就行。

TASK #3 - PARALLEL BUFFER POOL MANAGER

这部分其实看了需求就会知道,是最简单的一部分,只需要对之前两部分进行调用就行了,没有太大问题。

3.1 线程安全

这个管理器不需要设置锁,只需要在replacerbpli设置锁就行。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
CMU 15445 课程的 Project 0 是一个调试练习,旨在帮助学生熟悉调试工具和技术。在这个项目中,你将开始使用 GDB 和 Valgrind 这两个常用的调试工具,以及一些其他辅助工具。以下是一些问题和步骤,帮助你完成这个练习: 1. 你需要查看项目中提供的代码,并了解它的结构和功能,这样你才能更好地理解程序的逻辑和可能出现的 bug。 2. 接下来,你需要编译项目,并确保没有编译错误。如果出现错误,你需要修复它们,这可能需要检查一些语法错误或缺失的库。 3. 一旦成功编译项目,你就可以使用 GDB 进行调试了。GDB 是一个强大的调试器,可以帮助你找出程序中的错误。你可以使用 GDB 来单步执行代码、设置断点、查看变量的值等等。通过使用 GDB,你可以逐步查看代码运行的路径,并找出程序崩溃或产生错误的原因。 4. 在使用 GDB 进行调试时,你可以通过设置断点来暂停程序的执行,并查看变量的值和程序的状态。你可以使用“break”命令在程序中设置断点,并通过“run”命令启动程序。当程序到达这个断点时,它会停止执行,你可以使用“print”命令查看变量的值,或者“step”命令逐步执行代码。 5. 另一个常用的调试工具是 Valgrind。Valgrind 可以帮助你检测内存泄漏和错误的访问方式。你可以使用“valgrind”命令来运行程序,并查看 Valgrind 的输出。它会告诉你有关程序中任何潜在问题的信息,例如未初始化的变量、访问越界等。 6. 最后,当你发现 bug 并修复它们后,可以运行各种测试用例来验证程序的正确性。测试用例可以帮助你确定程序是否按预期工作,并且在修改代码后,它们可以帮助你确保你的修复没有引入新的错误。 通过完成 CMU 15445 项目 0 的调试练习,你将掌握一些重要的调试技巧和工具,这对于进一步开发和调试软件应用程序将非常有用。希望上述步骤和建议对你有所帮助,祝你顺利完成这个项目!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值