CS3103留学生作业代做、代写Dynamic Memory作业、代做C/C++语言作业、代写C/C++程序作业
CS3103 Operating SystemsSemester A 2018/19Project: Dynamic Memory AllocationDue Date: Friday, December 7th, 2018. Turn in hard copy in class and submit sourcecode in Canvas.I. Project OrganizationIn this project, you’ll write a dynamic memory allocator for C programs, i.e., your own versionof the malloc and free functions. The project can be done in groups, where each group canhave a maximum of three members. Each group should do the following pieces to completethe project. Each piece is explained below: Design 30 points Code 20 points Input/Output 40 points Summary 10 pointsDesignThe design space of building an allocator is large, with numerous alternatives for block formatand free list format, as well as placement, splitting, and coalescing policies. Free block organization: How do you keep track of free blocks? Placement: How do you choose an appropriate free block in which to place a newlyallocated block? Splitting: After you place a newly allocated block in some free block, what do you dowith the remainder of the free block? Coalescing: What do you do with a block that has just been freed?A practical allocator that strikes a better balance between throughput and utilization mustconsider the above issues. Describes the structure of your free and allocated blocks, theorganization of the free list, and how your allocator manipulates the free list. List and describeall the functions used in this project.CodeYour code should be nicely formatted with plenty of comments. Each function should bepreceded by a header comment that describes what the function doe. The code should be easyto read, properly indented, employ good naming standards, good structure, and should correctlyimplement the design. Your code should match your design.Input/OutputWe provide a trace-driven driver program that allows you to test your memory allocator forcorrectness, space utilization, and throughput. The driver program is controlled by a set of trace - 2 -files. Each trace file contains a sequence of allocate and free directions that instruct the driverto call your malloc and free functions in some sequence. The driver and the trace files arethe same ones we will use when we grade your source code.You will receive zero points for this part if your code is buggy and crashes the driver.Otherwise, your grade will be calculated as follows: Correctness (10 points). You will receive full points if your solution passes thecorrectness tests performed by the driver program. You will receive partial credit foreach correct trace. Performance (30 points). Two performance metrics will be used to evaluate yoursolution: (1) Space utilization: The peak ratio between the aggregate amount of memoryused by the driver (i.e., allocated via your malloc but not yet freed via free) and thesize of the heap used by your allocator. (2) Throughput: The average number ofoperations completed per second. Since space utilization and throughput are oftenconflicting performance goals, you must achieve a balance between utilization andthroughput to get a good score.The driver program summarizes the performance of your allocator by computing aperformance index, 0 ≤ P ≤ 100, which is a weighted sum of space utilization U andthroughput T relative to a baseline through Tlibc:P =100 * ( 0.6U + 0.4min(1, T/Tlibc))The value of Tlibc is 5000K ops/second.SummaryThe summary section should discuss any difficulties encountered, what was learned, and results.Each group member’s responsibility and efforts need to be listed in detail. It should be at leastone page in length.Language/PlatformThe project should be written in ANSI standard C.This project can be done on Linux (recommended), MacOS, or Windows using Cygwin. Sincegrading of this project will be done using cs3103-01 Linux server, students who choose todevelop their code on any other machine are strongly encouraged to run their programs on thecs3103-01 Linux server before turning it in. There will be no credit for programs that do notcompile and run on cs3103-01 Linux server, even if they run somewhere else.- 3 -II. Project DescriptionIn this project, you will write a dynamic memory allocator which is described as follows.Dynamic memory allocation is a useful and important programming technique. The mostimportant reason that programs use dynamic memory allocation is that often they do not knowthe sizes of certain data structures until the program actually runs. For example, suppose weare asked to write a C program that reads a list of n ASCII integers, one integer per line, fromstdin into a C array. The input consists of the integer n, followed by the n integers to be readand stored into the array. The simplest approach is to define the array statically with some hardcodedmaximum array size. However, allocating arrays with hard-coded sizes like this is oftena bad idea. A better approach is to allocate the array dynamically, at run time, after the valueof n becomes known. With this approach, the maximum size of the array is limited only by theamount of available virtual memory.The C standard library (libc) provides an allocator known as the malloc package. Programsallocate blocks from the heap by calling the malloc function. Programs free allocated heapblocks by calling the free function. Dynamic memory allocators such as malloc maintainan area of a process’s virtual memory known historically as the heap and maintain the heapas a collection of various-sized blocks. Each block is a contiguous chunk of virtual memorythat is either allocated or free. An allocated block has been explicitly reserved for use by theapplication. A free block is available to be allocated. A free block remains free until it isexplicitly allocated by the application. An allocated block remains allocated until it is freed,either explicitly by the application, or implicitly by the memory allocator itself.Making a fast, space-efficient, scalable allocator that works well for a broad range of workloadsremains an on-going challenge in modern computer systems. The design space is large. Hereare some of the design options available to you: Data structures to organize free blocks:— Implicit free list— Explicit free list— Segregated free lists Algorithms to scan free blocks:— First fit/next fit— Blocks sorted by address with first fit— Best fitYou can pick (almost) any combination from the two. For example, you can implement anexplicit free list with next fit, a segregated list with best fit, and so on. Also, you can build ona working implementation of a simple data structure to a more complicated one. Beyondcorrectness, your goal is to produce an allocator that performs well in time and space. Note thatthis involves a trade-off. For space, you want to keep your internal data structures small. Also,while allocating a free block, you want to do a thorough (and hence slow) scan of the freeblocks, to extract a block that best fits our needs. For speed, you want fast (and hencecomplicated) data structures that consume more space. In general, we suggest that you startwith an implicit free list (a simple allocator based on an implicit free list is provided for yourreference), then change this to an explicit list, and then use the explicit list as the basis for afinal version based on segregated lists.- 4 -Getting StartedStart by downloading and unpacking mallocproj-handout.zip. The only source codefile you will be modifying and handing in is "mm.c". The "mdriver.c" program allows youto evaluate the performance of your solution.To build the driver, type "make" to the shell.To run the driver on the default trace files: $ ./mdriverThe output shows the performance index of your memory allocator, e.g., Perf index = 51 (util)+ 1 (thru) = 52/100.You can also pass the -v option to mdriver to get a detailed summary for each trace file: $ ./mdriver -vWhen you have completed the project, you will hand in only one source code file, "mm.c",which contains your solution. Keep in mind that any changes you may have made to any of theother files will not be considered when grading!How to Work on the LabYour dynamic storage allocator will consist of the following three functions, which aredeclared in "mm.h" and defined in "mm.c": int mm_init(void); void *mm_malloc(size_t size); void mm_free(void *ptr);The "mm.c" file that we have given you implements the simple but still functionally correctmalloc implementation that based on an implicit free list. Using this as a starting place,modify these functions (and possibly define other private, static functions), so that theyobey the following semantics: mm_init: Before calling mm_malloc or mm_free, the application program (i.e.,the trace-driven driver program that you will use to evaluate your implementation) callsmm_init to perform any necessary initialization, such as allocating the initial heaparea. The return value should be -1 if there was a problem in performing theinitialization, 0 otherwise.The mm_init function will be called once per benchmark run, so it can be calledmultiple times in the same run of mdriver. Your mm_init function should resetyour implementation to its initial state in each case. mm_malloc: The mm_malloc function returns a pointer to an allocated blockpayload of at least size bytes, where size is less than 232. The entire allocated blockshould lie within the heap region and should not overlap with any other allocated block.- 5 -We’ll compare your implementation to the version of malloc supplied in libc. Sincethe libc malloc always returns payload pointers that are aligned to 8 bytes, yourmalloc implementation should do likewise and always return 8-byte aligned pointers.The driver will enforce this requirement for you. The ALIGNMENT value of 8 bytes isencoded in the macro ALIGNMENT defined in "config.h". mm_free: The mm_free function frees the block pointed to by ptr. It returnsnothing. This routine is only guaranteed to work when the passed pointer (ptr) wasreturned by an earlier call to mm_malloc and has not yet been freed.These semantics match the corresponding libc malloc and free functions.Support FunctionsThe "memlib.c" module provides a thin wrapper on the operating system’s virtual memorysystem. You can invoke the following functions from "memlib.c": void *mem_sbrk(int incr)Expands the heap by incr bytes, where incr is a positive non-zero integer andreturns a generic pointer to the first byte of the newly allocated heap area. Thesemantics are identical to the system's sbrk function, except that mem_sbrk acceptsonly a positive non-zero integer argument. void *mem_heap_lo(void)Returns a generic pointer to the first byte in the heap. void *mem_heap_hi(void)Returns a generic pointer to the last byte in the heap. size t mem_heapsize(void)Returns the current size of the heap in bytes. size t mem_pagesize(void)Returns the system’s page size in bytes (4K on Linux systems).Heap Consistency CheckerDynamic memory allocators are notoriously tricky beasts to program correctly and efficiently.They are difficult to program correctly because they involve a lot of untyped pointermanipulation. You will find it very helpful to write a heap checker function mm_checkheapthat scans the heap and checks it for consistency. This function will be very useful in debuggingyour malloc implementation. Some malloc bugs are very hard to debug using conventionalgdb techniques. The only effective technique for some of these bugs is to use a heapconsistency checker. When you encounter a bug, you can isolate it with repeated calls to theconsistency checker until you find the instruction that corrupted your heap. If you ask a memberof the course TAs for help, the first thing we will do is ask to see your heap consistency checkerfunction, so please write this function before coming to see us!Some examples of what your heap checker should check are provided below. Checking the heap (implicit list, explicit list, segregated list):— Check epilogue and prologue blocks.— Check block’s address alignment.— Check heap boundaries.- 6 -— Check each block’s header and footer: size (minimum size, alignment), prev/nextallocate/free bit consistency, header and footer matching each other.— Check coalescing: no two consecutive free blocks in the heap. Checking the free list (explicit list, segregated list):— All next/prev pointers are consistent (if A’s next pointer points to B, B’s prevpointer should point to A).— All free list pointers points between mem_heap_lo() andmem_heap_high().— Count free blocks by iterating through every block and traversing free list bypointers and see if they match.— All blocks in each list bucket fall within bucket size range (segregated list).You may find it useful to insert a call just before your mm_malloc or mm_free functionreturns for consistency checking. This consistency checker is for your own debugging duringdevelopment. Before you submit "mm.c", however, make sure to remove or comment out anycalls to your checker, since it will slow down throughput.Trace-based Driver ProgramThe provided Makefile combines "mdriver.c" with your "mm.c" to create the driverprogram mdriver, which accepts the following command line arguments: -t tracedir — Look for the default trace files in directory ?tracedir? instead of thedefault directory that is defined in "config.h". -f tracefile — Use one particular ?tracefile? for testing instead of the default set oftrace files. -h — Print a summary of the command line arguments. -l — Run and measure libc malloc in addition to the "mm.c" mallocimplementation. -v — Verbose output, printing a performance breakdown for each trace file in acompact table. -V — More verbose output, printing additional diagnostic information as each trace fileis processed. This flag is useful during debugging to determine which trace file iscausing your malloc implementation to fail.The normal operation is to run it with no arguments, but you may find it useful to use thearguments during development.A trace file is an ASCII (plain text) file. It begins with a 4-line header: suggested heap size(unused), number of request id's, number of requests (operations), and weight for this trace(unused). The header is followed by the number of requests text lines. Each line denotes eitheran allocate [a] or free [f] request with an id that uniquely identifies an allocate or free request.Please refer to the README file in the trace directory for more details. We encourage you tostudy the trace files and optimize for them, but your code must be correct on every trace. Youmay find it useful to see the shape of memory use created by a trace file. We provide plots ofallocated memory over time for the provided trace files in traces/plot directory.Programming Rules You must not change any of the interfaces in "mm.h".- 7 - You must not invoke any memory-management related library calls or system calls,including malloc, calloc, free, sbrk, brk, or any variants of these calls. Usingthese calls would not make sense because this project asks you to implement theirfunctionality. You must not define any global or static compound data structures such as arrays,structs, trees, or lists in your "mm.c" program. However, you are allowed to declaretypes (including struct types) in "mm.c", and you are allowed to declare global scalarvariables such as integers, floats, and pointers in "mm.c".The reason for this restriction is that the driver cannot account for such global variablesin its memory utilization measure. If you need space for large data structures, you canput them at the beginning of the heap. You must not implement a pure implicit list allocator (the CS:APP book comes withan example of how to do that, see Resources section). If you do so, you will receiveno credit.Hints Understand every line of the malloc implementations in CS:APP book and the provided"mm.c". The textbook and "mm.c" both have a detailed example of a simple allocatorbased on an implicit free list. Use them as a point of departure. Don’t start working onyour allocator until you understand everything about the implicit-list allocator. Use the mdriver -f option. During initial development, using tiny trace files willsimplify debugging and testing. We have included two such trace files, "short1-bal.txt" and "short2-bal.txt", that you can use for initial debugging. Use the mdriver -v and -V options. The -v option will give you a detailedsummary for each trace file. The -V will also indicate when each trace file is read,which will help you isolate errors. Use the mdriver -l options. The -l option will run libc malloc. It can be usedto warm up the processor and cache before running your functions. Compile with gcc -g and use a debugger. A debugger will help you isolate andidentify out of bounds memory references. Modify the Makefile to pass the -g optionto gcc and not to pass the -O2 option to gcc when you are using a debugger. But donot forget to restore the Makefile to the original when doing performance testing. Afterchanging the Makefile, do make clean. Encapsulate your pointer arithmetic in inline functions or C preprocessor macros.Pointer arithmetic in memory managers is confusing and error-prone because of all thecasting that is necessary. You can reduce the complexity significantly by writingmacros for your pointer operations. If you use macros, put each use of a macro argumentin parentheses within the macro definition, and always put parentheses around the righthandside of a macro definition. Otherwise, it’s easy to write macros that parsedifferently than you expect when the macro is textually expanded. Remember we are working with 64-bit machines. Pointers take up 8 bytes of space.Notably, on 64-bit machines, sizeof(size_t) == 8. We pass the -m64 option togcc in the Makefile to make it compatible with mainstream operating systems, sincethe i386 architecture is deprecated for macOS. Use your heap consistency checker. A good heap consistency checker will save youhours and hours when debugging your malloc package. Your heap checker shouldscan the heap, performing sanity checks and possibly printing out useful debugginginformation. Every time you change your implementation, one of the first things you - 8 -should do is think about how your heap checker function will change, what sort of testsneed to be performed, and so on. Consider edge conditions. Consider the case that a block that is freed may not have aleft or right neighbour. A possible strategy is to initialize your heap such that it willappear that there are always allocated “fence” blocks to the left and to the right, whichmeans that the above case never arises. Consider small requests. Depending on which strategy you choose, you will need toround up small requests. Don’t just think about what happens when allocating a block,consider also what you’ll have to do when freeing this block. Freeing the block mayinclude inserting the block into your free list or lists (or other data structure if youimplement one), and thus it must be large enough to hold all link elements plusboundary tags (if used). You will need to consider this both when requesting morememory via mem_sbrk() and when splitting a block that may be too large. Use a profiler. You may find the Valgrind's tool suite, including Callgrind andCachegrind tools, helpful for optimizing performance. Complete your implementation in stages. Get a basic implementation working, and thenmodify it to improve performance. Keep backups and versioning your implementation. Whenever you have a workingallocator and are considering making changes to it, keep a backup copy of the lastworking version. It is very common to make changes that inadvertently break the codeand then have trouble undoing them. Now would also be a great time to learn anindustrial-strength version control system like Git. Start early!- 9 -III. Project GuidelinesSubmissionLooking at the file "mm.c" you’ll notice a C structure group into which you should insertthe requested identifying information about your project group. You're required to join a projectgroup in Canvas and provide your group number. Please use your CityU email accounts(@my.cityu.edu.hk) for the email addresses. Do this right away so you don’t forget.Submit your project with hard copy and soft copy on or before December 7th, 2018. Includein your submission the following files:1) A Word/PDF document for the design and summary of the project (hard copy &soft copy);2) The source file, i.e., mm.c (soft copy);Each group needs to upload the document and source code to Canvas.Go to the “Assignments” => “Project” => “Submit Assignment” and upload your files.Academic HonestyAll work must be developed by each group separately. Please write your own code. Allsubmitted source code will be scanned by anti-plagiarism software. If the code does notwork, please indicate in the report clearly.Resources[CS:APP] "Computer Systems: A Programmer's Perspective, Second Edition" by Randal E.Bryant and David R. O'Hallaron, Pearson. This book gives a detailed example of a simpleallocator based on an implicit free list in Section 9.9 Dynamic Memory Allocation. You canfind this year and previous years' lecture slides and lecture videos from course web pagehttp://www.cs.cmu.edu/~213/.[OS:TEP] "Operating Systems: Three Easy Pieces " by Remzi H. Arpaci-Dusseau and AndreaC. Arpaci-Dusseau, Arpaci-Dusseau Books March, 2015 (Version 1.00) . An excellent freeonline operating systems book. In Chapter 17 Free Space Management, the authors discuss theissues surrounding free-space management. The book is available athttp://pages.cs.wisc.edu/~remzi/OSTEP.http://www.daixie0.com/contents/13/2164.html[DSA] "Dynamic Storage Allocation: A Survey and Critical Review" by Paul R. Wilson,Mark S. Johnstone, Michael Neely, David Boles. International Workshop on MemoryManagement, Scotland, UK, September 1995. An excellent and far-reaching survey of manyfacets of memory allocation. It is nearly 80 pages long; thus, you really have to be interested!This paper is available at http://csapp.cs.cmu.edu/3e/docs/dsa.pdf.
因为专业,所以值得信赖。如有需要,请加QQ:99515681 或邮箱:
微信:codinghelp