撰写本文的目的:记录本人在不参考其他任何形式的解决方法(思路/源码)、仅靠课程提供的资源(课本/参考资料)和Discord
中high level
的讨论的情况下,独立完成该课程的过程。
欢迎大家和我讨论学习中所遇到的问题。
由于gradescope
中对non-cmu students
仅开放了Project#0
,本文方法仅通过了本地测试,极有可能有错误(并发访问)
目前通过了GradeScope
所有测试并且拿到了100.0/100.0
,但是性能较差(与Leaderboard
上第一名有十倍的性能差距),打算在下一篇文章记录一下对BPM
的性能进行优化,例如本文中提到的DiskScheduler
创建的对Request
的处理Thread
实际上是串行的,后续再保证顺序正确的情况下对其进行适当的并行处理。
Task#1 - LRU-K Replacement Policy
思路:
- 基本可以参考源码中给出的注释,一步一步实现
- 每次
RecordAccess
一个Frame
时,都会使得leu_replacer
的current_timestamp_
自增1,方便挑选被evict
的frame
。 - 在计算
k backwrad distance
时,使用UINT32_MAX
代替题目中所述的+inf
- 由于
LRUNode
的成员变量都是私有成员,题目规定不能更改函数或者成员的signature
,因此需要自己定义多个setter
和getter
方法 - 为了方便
Evict
方法的实现,可以在LRUNode
中实现GetKDistance
方法
Size
直接返回维护的curr_size_
。
RecordAccess
- 判断frame_id是否有效
- 判断node_store中是否已经存在对应该frame_id的LRUNode
- 若未存在,则创建临时LRUNode,并更新node的访问历史,将其插入node_store_
- 若已经存在,则只是更新访问历史
- lru_replacer的current_timestamp自增1
SetEvictable
按照注释一步一步实现,需要注意更新curr_size_
Evict
- 定义两个临时变量记录最大的time stamp difference和对应的frame id
- 定义一个vector,记录所有k backward distance为+inf的frame id
- 遍历一遍frame node
- 通过最大的time stamp difference,若为+inf,则遍历vector找到earliest access history以及对应的frame id
Remove
按照注释实现即可
Bugs
- [✅] 未给方法中任意位置加锁时能够通过测试,可能本地测试并没有涉及到对某个成员变量的竞争。但是加锁后测试就会卡住