《深入理解计算机系统》实验七Molloc Lab 下载和官方文档机翻

前言

《深入理解计算机系统》官网:http://csapp.cs.cmu.edu/3e/labs.html
该篇文章是
实验七Molloc Lab的Writeup(malloclab.pdf)机翻
原文:http://csapp.cs.cmu.edu/3e/malloclab.pdf

在官网点击下方即可下载实验七的文件
在这里插入图片描述

官网下载的文件没有测试文件traces
可以在这里下载《深入理解计算机系统》实验七Molloc Lab测试文件traces(0积分下载)
放入实验文件夹中
打开config.h
在这里插入图片描述
改默认配置地址
在这里插入图片描述
在目录下运行一下命令,即可查看成绩。

linux> make
linux>./mdriver -V

1 介绍

在这个实验中,你将为C程序编写一个动态存储分配器,也就是你自己版本的malloc, free和realloc例程。我们鼓励您创造性地探索设计空间,并实现一个正确、高效和快速的分配程序。

2 组织工作

你可以在多达两个人的小组中工作。任何对作业的澄清和修改将在课程网页上公布。

3 发指令

特定地点:在这里插入一段解释学生应该如何下载malloclab-handout.tar文件。

首先将malloclab-handout.tar复制到一个受保护的目录中,您计划在这个目录中执行您的工作。然后输入命令:tar xvf malloclab-handout.tar。这将导致大量文件被解压缩到目录中。你唯一需要修改和提交的文件是mm.c。mdriver.c程序是一个驱动程序,允许您评估解决方案的性能。使用命令make生成驱动程序代码,并使用命令。/mdriver -V。(-V标志显示有用的摘要信息。)

查看文件mm.c,您会注意到一个C结构团队,您应该向其中插入所请求的关于组成您的编程团队的一两个个人的标识信息。马上做,这样你就不会忘记了。

当你完成了实验,你将只交一个文件(mm.c),其中包含你的解决方案。

4 如何在实验室工作

您的动态存储分配器将由以下四个函数组成,它们在mm.h中声明,在mm.c中定义。
在这里插入图片描述
我们给您的mm.c文件实现了我们所能想到的最简单但在功能上仍然正确的malloc包。使用这个函数作为起点,修改这些函数(也可能定义其他私有静态函数),使它们遵循以下语义:

  • mm_init:在调用mm_malloc mm_realloc或mm_free之前,应用程序(即,您将用于评估您的实现的跟踪驱动程序)调用mm_init来执行任何必要的初始化,例如分配初始堆区域。如果在执行初始化时出现问题,则返回值应为-1,否则为0。
  • mm_malloc:mm_malloc例程返回一个指针,指向已分配的至少大小字节的块有效负载。整个分配的块应该位于堆区域内,并且不应该与任何其他分配的块重叠。
    我们将把您的实现与标准C库(libc)中提供的malloc版本进行比较。由于libc malloc总是返回对齐到8字节的有效负载指针,所以您的malloc实现也应该这样做,并且总是返回对齐到8字节的指针。
  • mm_free:mm_free例程释放ptr指向的块。它什么也不返回。只有当传递的指针(ptr)由先前对mm_malloc或mm_realloc的调用返回且尚未释放时,此例程才能保证工作。
  • mm_realloc:mm_realloc例程返回一个指针,该指针指向一个至少具有字节大小的已分配区域,并具有以下约束。
    • 如果ptr为NULL,调用等价于mm_malloc(size);
    • 如果size等于0,则调用等价于mm_free(ptr);
    • 如果ptr不是NULL,它必须由先前调用mm_malloc或mm_realloc返回。调用mm_realloc将ptr(旧块)指向的内存块的大小更改为字节大小,并返回新块的地址。请注意,新块的地址可能与旧块相同,也可能不同,这取决于您的实现、旧块中的内部碎片的数量以及realloc请求的大小。
      新块的内容与旧的ptr块相同,直到新旧大小的最小值为止。其他的都没有初始化。例如,如果旧块是8个字节,新块是12个字节,那么新块的前8个字节与旧块的前8个字节相同,最后4个字节未初始化。类似地,如果旧块是8个字节,新块是4个字节,那么新块的内容与旧块的前4个字节相同。

这些语义与相应的libc malloc、realloc和free routines的语义相匹配。在shell中输入man malloc以获得完整的文档。

5 堆一致性检查

动态内存分配器对于正确和有效地编程来说是非常棘手的。它们很难正确地编程,因为它们涉及大量的非类型化指针操作。您会发现编写一个堆检查器非常有用,它扫描堆并检查其一致性。
以下是堆检查器可能检查的一些例子:

  • 空闲列表中的每个块都标记为空闲吗?
  • 是否有一些相邻的自由块以某种方式逃避了合并?
  • 每个空闲块都在空闲列表中吗?
  • 空闲列表中的指针指向有效的空闲块吗?
  • 分配的块是否有重叠?
  • 堆块中的指针指向有效的堆地址吗?

你的堆检查器将由mmc中的int mm_check(void)函数组成。它将检查任何你认为谨慎的不变量或一致性条件。当且仅当堆一致时,它返回一个非零值。您不局限于列出的建议,也不需要检查所有的建议。当mm_check失败时,建议输出错误信息。
这个一致性检查器可以在开发期间用于您自己的调试。当您提交mm.c时,请确保删除对mm_check的任何调用,因为它们会降低您的吞吐量。样式点将被指定给你的mm_check函数。一定要把你检查的内容写进注释和文档。

6 支持例程

memlib.c包模拟动态内存分配器的内存系统。你可以在memlib.c中调用以下函数:

  • void *mem sbrk(int incr):以incr字节扩展堆,其中incr是一个正的非零整数,并返回一个指向新分配的堆区域的第一个字节的通用指针。其语义与Unix sbrk函数相同,只是mem sbrk只接受一个正的非零整数参数。
  • void *mem_heap_lo(void):返回一个指向堆中第一个字节的通用指针。
  • void *mem_heap_hi(void):返回一个指向堆中最后一个字节的通用指针。
  • size_t mem heapsize(void):以字节为单位返回堆的当前大小。
  • size_t mem pagesize(void):以字节为单位返回系统的页面大小(在Linux系统上是4K)。

7 跟踪驱动程序

tar分发版中的驱动程序mdriver.c测试mm.c包的正确性、空间利用率和吞吐量。驱动程序由malloclab-handout.tar发行版中包含的一组跟踪文件控制。每个跟踪文件包含一个分配、重新分配和自由方向序列,指示驱动程序以某种顺序调用mm_malloc、mm_realloc和mm_free例程。驱动程序和跟踪文件是我们在给您的handin mm.c文件评分时将使用的相同文件。

驱动程序mdriver.c接受以下命令行参数:

  • -t <tracedir>:在tracedir目录中查找默认的跟踪文件,而不是config.h中定义的默认目录。
  • -f <tracefile>:使用一个特定的tracefile来测试,而不是默认的tracefile集合。
  • -h:输出命令行参数的摘要。
  • -l:运行和测量libc malloc,除了学生的malloc包。
  • -v:详细的输出。在一个紧凑的表格中打印每个跟踪文件的性能分类。
  • -V:更详细的输出。在处理每个跟踪文件时打印附加的诊断信息。在调试期间,有助于确定是哪个跟踪文件导致malloc包失败。

8 编程规则

  • 你不应该改变mm.c中的任何接口。
  • 您不应该调用任何与内存管理相关的库调用或系统调用。这排除了在你的代码中使用malloc, calloc, free, realloc, sbrk, brk或这些调用的任何变体。
  • 你不能在你的mm.c程序中定义任何全局或静态的复合数据结构,如数组、结构体、树或列表。但是,在mm.c中可以声明全局标量变量,比如整数、浮点数和指针。
  • 为了与libc malloc包(它返回按8字节边界对齐的块)保持一致,你的分配器必须总是返回按8字节边界对齐的指针。驱动程序将为您执行此要求。

9 评估

如果你违反任何规则或你的代码是bug和崩溃的驱动程序,你将得到零分。否则,你的成绩将按以下方式计算:

  • 正确性(20分)。如果您的解决方案通过驱动程序执行的正确性测试,您将获得满分。每个正确的跟踪都将获得部分积分。
  • 性能(35分)。两个性能指标将用于评估您的解决方案
    • 空间利用率:驱动程序使用的累计内存总量(即,通过mm_malloc或mm_realloc分配,但尚未通过mm_ free释放)与分配程序使用的堆大小之间的峰值比率。最优比率为1。为了让这个比例尽可能接近最优,你应该找到一些好的策略来最小化碎片。
    • 吞吐量:每秒完成的操作的平均数量。

驱动程序通过计算一个性能指标P来总结分配器的性能,P是空间利用率和吞吐量的加权和
在这里插入图片描述
其中U是你的空间利用率,T是你的吞吐量,Tlibc是libc malloc在默认跟踪系统上的估计吞吐量。性能索引更倾向于空间利用率,而不是吞吐量,默认值为w = 0.6。
注意到内存和CPU周期都是昂贵的系统资源,我们采用这个公式来鼓励内存利用率和吞吐量的平衡优化。理想情况下,性能指标将达到P = w +(1−w) = 1或100%。由于每个指标对性能指数的贡献分别最多为w和1−w,所以您不应该走极端,只优化内存利用率或吞吐量。要获得良好的分数,您必须在利用率和吞吐量之间取得平衡。

  • 风格(10分)。
    • 你的代码应该被分解成函数,并且使用尽可能少的全局变量。
    • 你的代码应该以一个头注释开始,它描述了你的空闲块和已分配块的结构,空闲列表的组织,以及你的分配器如何操作空闲列表。每个函数之前应该有一个描述函数功能的头注释。
    • 每个子例程都应该有一个头注释来描述它做了什么以及它是如何做的。
    • 您的堆一致性检查器mm_check应该是彻底的和有良好文档的。

好的堆一致性检查器可以得5分,好的程序结构和注释可以得5分。

10 提交指令

特定地点:在这里插入一段解释学生应该如何提交他们的解决方案mm.c文件。

11 提示

  • 使用mdriver -f选项。在初始开发阶段,使用微小的跟踪文件将简化调试和测试。我们已经包含了两个这样的跟踪文件(short1,2-ball .rep),您可以使用它们进行初始调试。
  • 使用mdriver -v和-V选项。v选项将为您提供每个跟踪文件的详细摘要。V还将指示何时读取每个跟踪文件,这将帮助您隔离错误。
  • 使用gcc -g编译并使用调试器。调试器将帮助您隔离和识别超出边界的内存引用。
  • 理解课本中malloc实现的每一行。课本中有一个基于隐式自由列表的简单分配器的详细示例。使用这是一个出发点。在理解了关于简单隐式列表分配程序的所有内容之前,不要开始处理分配程序。
  • 用C预处理器宏封装你的指针算法。内存管理器中的指针运算是令人困惑和容易出错的,因为所有的强制转换都是必要的。您可以通过为指针操作编写宏来显著降低复杂性。请看文本中的例子。
  • 分阶段执行您的实现。前9个跟踪包含对malloc和free的请求。最后2个跟踪包含对realloc、malloc和free的请求。我们建议您首先让malloc和free例程在前9个跟踪上正确有效地工作。只有这样,您才能将注意力转向realloc实现。首先,在现有malloc和free实现的基础上构建realloc。但要获得真正好的性能,您需要构建一个独立的realloc。
  • 使用一个分析器。您可能会发现gprof工具有助于优化性能。
  • 早点出发!用几页代码编写一个高效的malloc包是可能的。但是,我们可以保证,它将是您迄今为止所编写的最困难和最复杂的代码之一。所以,早点开始吧,祝你好运!
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值