这是一个本人学习 csapp 的 learning 库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

63 lines
3.0 KiB

  1. ## 关于示例代码的理解
  2. #### 环境
  3. *`mem_init` 中可以看出整个分配器是在一大段已经分配好的连续的内存中进行的
  4. * 同样每次 `mem_sbrk` 进行扩展时也是连续扩展,模拟堆的向上增长
  5. #### 对齐
  6. * 标准 `malloc` 也是八字节对齐,所以可以满足强制八字节对齐的要求
  7. * 返回的内存应为有效载荷部分,如果每个块加上头部和脚部,为了满足对齐要求,须在开头空出四字节的位置
  8. * 也意味着空闲块最小为八字节大小,有效载荷也应八字节对齐,已分配块最小十六字节
  9. #### 测试
  10. * handout 里的测试用例偏少,从网上找到了更为详尽的 `traces` 测试用例来测试
  11. ## version 1
  12. #### 规则与注意
  13. 理解逻辑后,接下来将实现自己的版本
  14. * 为方便理解,定义了两个类型别名
  15. ```c
  16. typedef unsigned int word;
  17. typedef char byte;
  18. ```
  19. * 不同于示例代码用序言块和尾块标记,本人仅用两个指针标记头尾,来提高内存利用率
  20. ```c
  21. // mark the front and tail pos
  22. void *front_p = NULL;
  23. void *tail_p = NULL;
  24. ```
  25. * 但会增加代码的复杂度,需着重维护
  26. * 同时还应注意若 `bp == front_p``PREV(bp)` 内的值无效,`tail_p` 同理
  27. * 为保持一致性,向辅助函数内传入的 `size` 均应在传入之前对齐,均不包含头尾部大小
  28. * 仅在内部碎片大于等于十六字节时才进行切割
  29. * 其他部分与示例大同小异
  30. #### bug 与 debug
  31. * `#debug`对于 `segmentation fault` 使用 `gdb` 获取头尾块的 `size` 发现尾部异常值 `0xcdcdcd`,在代码中使用 `print` 跟踪 `trail_p` 变量,发现在`__coalesce_next`处没有及时更新
  32. * `#bug1` 若记录的 `size` 是有效载荷的 `size`,合并和分割时应注意增减 `DSIZE`
  33. * `#bug2` 每次合并都需要判断 `tail_p` 是否改变,特别是 `__coalesce_next` 的情况
  34. #### 方法与得分
  35. * 隐式空闲链表,首次适配,立即合并
  36. ```c
  37. Results for mm malloc:
  38. trace valid util ops secs Kops
  39. 0 yes 99% 5694 0.007579 751
  40. 1 yes 100% 5848 0.006639 881
  41. 2 yes 99% 6648 0.010560 630
  42. 3 yes 100% 5380 0.008016 671
  43. 4 yes 100% 14400 0.000102140762
  44. 5 yes 92% 4800 0.006677 719
  45. 6 yes 92% 4800 0.005988 802
  46. 7 yes 55% 12000 0.141468 85
  47. 8 yes 51% 24000 0.274197 88
  48. 9 yes 33% 14401 0.128358 112
  49. 10 yes 50% 14401 0.002138 6734
  50. Total 79% 112372 0.591722 190
  51. Perf index = 47 (util) + 13 (thru) = 60/100
  52. ```
  53. ## Version 1.1
  54. #### 针对 `realloc` 的优化 v1
  55. *`new_size <= old_size` 则不分配而是切割
  56. * 若下一块未分配且总和大于 `new_size` 则合并
  57. * 若合并后内部碎片过大则仍需分割
  58. * 提高六分,但判断过多,且考虑不全
  59. #### 针对 `realloc` 的优化 v2
  60. * 评估前后空闲块的总大小,若足够,则合并
  61. * 合并不会破坏数据,合并后复制数据,再根据需要分割
  62. ***
  63. 2022.12.29 ~ 2022.12.30