ICS malloc lab总结

来源:互联网 发布:mac 启动 文件夹 问号 编辑:程序博客网 时间:2024/05/16 15:53

ICS malloc lab总结


lab要求

你要实现一个malloc系列函数,并且实现比较好的性能以获得分数,衡量函数性能的标准为内存空间利用率(util,总共61分)及分配算法的时间复杂度(thru,总共39分)。

PKU的标准是92% util+13000Kops thru是满分,如果你某一项少了就要扣分,但是如果你某一项少到一定程度或者某一个应该分配成功的trace分配失败了(往往因为为了追求thru而造成过多的外部和内部碎片),那么你的整个lab就0分了。

注意:thru吞吐量单位为每秒,而不是每时钟周期,所以不同人电脑上CPU主频不一样, 所以同样的程序在不同电脑上得分不一样, 不过不用担心不公平,因为最后得分都是以服务器主频为标准的。


lab主要解法

历史上大家都认为为了得到满分(98+/100),写一个单个操作平均复杂度O(logN)的BST是必要的,甚至有时候BST退化严重的话,是得不到满分的,所以只有平衡树比较保险。(所以很多人做之前先参考网上代码,写了一个平衡树,导致malloc lab网上流传的答案全是平衡树或BST版本,大家为了拿满分,都采用了平衡树,代码也都差不多。
当然,学习别人的代码在自己写是没有问题的,但是希望大家不要抄袭,像malloc lab你自己写和抄袭别人的代码再改一改(封装一些语句为函数,把代码改写为同义语句,改变模块顺序等伎俩),根本骗不过Stanford moss查重系统,而shell lab被发现相似度高问题还不大,毕竟这个lab大家都应该写的差不多,你说思路刚好巧合很正常…要是malloc lab被发现相似度高,你说没抄袭,谁都不信是吧。

但是事实上还有其他写法也是可以满分的,但是其他写法性能不如平衡树/BST。

以下为主要解法:
BST/平衡树版本,这是最优秀的版本,写的话的话thru可以做到满分标准两倍还有多,可以98+/100。
free什么事情都不干的版本(mm-naive.c),由于不能很好利用空间是会失败的。
课本里的版本,由于首次适配利用率不高,也是失败的。
一般的链表O(N)复杂度如果首次适配很有可能利用率不高,会失败。
一般的链表O(N)复杂度如果最佳适配,因为复杂度太高,应该能得到一个比较低的分数。
一般的分离适配+显式链表,可以得到不错的分数,大概75/100-85/100,有的博客宣称可以做到91/100。


我的解法简述

参数

./mdriver

91%util 60/61
13000+Kops(autolab 1300MHz) 39/39
20000+Kops(My own PC 2200MHz) 39/39
99/100

PKU autolab

18 17 91% 153836 0.011493 13385

Comparison with libc malloc: mm/libc = 13385 Kops / 10391 Kops = 1.29
Perf index = 60 (util) & 39 (thru) = 99/100
{“scores”: {“Autograded Score”: 99}, “scoreboard”: [99, 99, 13385, 91]}

Score for this problem: 99.0

思路1:显式链表

空闲块有头部脚部,然后可以利用头部size(注意一个细节,虽然是64位机子,但是可以压缩地址为32位做,不过解码时候需要注意一些问题,具体看writeup)后3位一定是0,用来干一些其他事情。
拿一位记录本块是否分配。
拿一位记录前面的块是否分配,可以使得分配块不再有脚部,这是一个重要优化。

思路2:最小块优化

这样以来最小块大小是16字节,如果给你大量的malloc(1),就很浪费,那么理论上最小块可以到8字节大小,所以做一个优化,去掉8字节空闲块脚部,做一个最小块优化。
拿一位记录前面的块是否为8字节,可以使得8字节空闲块不再有脚部,这是一个重要优化,最小块大小降到了8字节
这样一来8字节的块就很特殊了,事实上通过宏可以让你编写代码是透明这一事实,当然链表中一些地方需要特殊讨论,问题不大。

思路3:分离适配

注意比较小的块比较多,所以可以单独拿一个链表来处理他们,事实上我的代码靠着O(N)的复杂度拿99/100,最关键的一点是分离适配,用不同链表处理不同大小空闲块。

思路4:维护链表关于块大小单调

单调不单调查询都是O(N),但是一旦单调那么首次适配约等于最优适配了。

提示:看课本和writeup

课本里的宏风格很不错,建议模仿课本风格。还有链表具体操作等等,建议先把课本和mm-naive.c看懂,writeup看清楚,比如writeup里提到的一个关于64位-32位的小细节可以利用,再开始做。
其他部分,例如合并空闲块之类的,可以参考课本和naive版本。

1 1
原创粉丝点击