diff --git a/labs/malloclab_lab/mdriver b/labs/malloclab_lab/mdriver index ad53776..bd8b7ce 100644 Binary files a/labs/malloclab_lab/mdriver and b/labs/malloclab_lab/mdriver differ diff --git a/labs/malloclab_lab/mm.c b/labs/malloclab_lab/mm.c index 710f1e0..922daa4 100644 --- a/labs/malloclab_lab/mm.c +++ b/labs/malloclab_lab/mm.c @@ -146,7 +146,7 @@ void mm_free(void *ptr) { /** * implemented simply in terms of mm_malloc and mm_free - * if size <= old_size, then cut instead of malloc and coalesce + * if size <= old_size, then return * if the rest blank are enough for the size, then coalesce * if too big, then cut again */ @@ -155,31 +155,31 @@ void *mm_realloc(void *ptr, size_t size) { if (size == 0) return NULL; void *new_ptr; - size_t old_size = SIZE(ptr); size_t adjust_size = ALIGN(size); + size_t old_size = SIZE(ptr); if (adjust_size <= old_size) { - if (old_size - adjust_size >= FSIZE) { - _place(ptr, adjust_size); // just cut - if (NEXT(ptr) != tail_p && !ALLOC(NEXT(NEXT(ptr)))) __coalesce_next(NEXT(ptr)); - } + // just return, for the memory lost is little return ptr; + } + size_t next_size = (ptr != tail_p && !ALLOC(NEXT(ptr))) ? SIZE(NEXT(ptr)) + DSIZE : 0; + size_t total_size = old_size + next_size; + if (adjust_size <= total_size) { + new_ptr = __coalesce_next(ptr); + _place(new_ptr, adjust_size); // just cut + return new_ptr; + } + size_t prev_size = (ptr != front_p && !ALLOC(PREV(ptr))) ? SIZE(PREV(ptr)) + DSIZE : 0; + total_size += prev_size; + if (adjust_size <= total_size) { // coalesce prev or all + new_ptr = _coalesce(ptr); + memmove(new_ptr, ptr, old_size); + _place(new_ptr, adjust_size); } else { - if (ptr != tail_p && !ALLOC(NEXT(ptr)) && SIZE(ptr) + SIZE(NEXT(ptr)) + DSIZE >= adjust_size) { - if (NEXT(ptr) == tail_p) tail_p = ptr; - size_t new_size = SIZE(ptr) + SIZE(NEXT(ptr)) + DSIZE; - SET(HEAD(ptr), PACK(new_size, 1)); - SET(FOOT(ptr), PACK(new_size, 1)); - if (SIZE(ptr) - adjust_size >= FSIZE) { - _place(ptr, adjust_size); - } - return ptr; - } - if ((new_ptr = mm_malloc(size)) == NULL) return NULL; - memcpy(new_ptr, ptr, old_size); + memmove(new_ptr, ptr, old_size); mm_free(ptr); - return new_ptr; } + return new_ptr; } // my func diff --git a/labs/malloclab_lab/mm.o b/labs/malloclab_lab/mm.o index fd45e14..d450ea2 100644 Binary files a/labs/malloclab_lab/mm.o and b/labs/malloclab_lab/mm.o differ diff --git a/labs/malloclab_lab/solve_note.md b/labs/malloclab_lab/solve_note.md index a9e2bd3..972dfb0 100644 --- a/labs/malloclab_lab/solve_note.md +++ b/labs/malloclab_lab/solve_note.md @@ -60,5 +60,30 @@ Perf index = 47 (util) + 13 (thru) = 60/100 #### 针对 `realloc` 的优化 v2 * 评估前后空闲块的总大小,若足够,则合并 * 合并不会破坏数据,合并后复制数据,再根据需要分割 +* 然而针对第九项测试,合并前后空闲块反而内存利用率低于仅合并后空闲块 +#### 针对 `realloc` 的优化 v3 +* 最终选择的是逐步的过程,因为从时间开销上来看,直接返回优于仅合并后部分优于合并前后部分,但同时合并前后部分与再分配一段内存的优劣不好比较 +* 现在的问题是在仅合并后部分和重新分配之间要不要插一段合并前后部分的条件,两者分数相同,个人认为插入这个条件通用性更好 +#### 得分 +```c +Results for mm malloc: +trace valid util ops secs Kops + 0 yes 99% 5694 0.007401 769 + 1 yes 100% 5848 0.006883 850 + 2 yes 99% 6648 0.011138 597 + 3 yes 100% 5380 0.008327 646 + 4 yes 100% 14400 0.000092156013 + 5 yes 92% 4800 0.006244 769 + 6 yes 92% 4800 0.005888 815 + 7 yes 55% 12000 0.142196 84 + 8 yes 51% 24000 0.277304 87 + 9 yes 50% 14401 0.018129 794 +10 yes 86% 14401 0.000132108933 +Total 84% 112372 0.483734 232 + +Perf index = 50 (util) + 15 (thru) = 66/100 +``` +## Version 1.2 + *** 2022.12.29 ~ 2022.12.30 \ No newline at end of file