Nachos虚拟内存机制实习报告

上传人:文*** 文档编号:60595408 上传时间:2022-03-08 格式:DOCX 页数:18 大小:157.60KB
收藏 版权申诉 举报 下载
Nachos虚拟内存机制实习报告_第1页
第1页 / 共18页
Nachos虚拟内存机制实习报告_第2页
第2页 / 共18页
Nachos虚拟内存机制实习报告_第3页
第3页 / 共18页
资源描述:

《Nachos虚拟内存机制实习报告》由会员分享,可在线阅读,更多相关《Nachos虚拟内存机制实习报告(18页珍藏版)》请在装配图网上搜索。

1、虚拟内存机制实习报告善良的大姐姐2015.4.18目录一:总体概述.3二:任务完成情况3任务完成列表(Y/N)3具体Exercise的完成情况3三:遇到的困难以及解决方法15四:收获及感想15五:对课程的意见和建议15六:参考文献15一:总体概述通过认真仔细阅读Nachos系统虚拟内存部分的源代码,理解虚拟内存的管理和应用机制,用户程序的运行逻辑,并修改源代码,达到“实现虚拟存储系统”的目标。二:任务完成情况任务完成列表(Y/N)ExerciselExercise2Exercise3Exercise4Exercise5Exercise6Exercise7Challengeyesyesyesye

2、syesyesyesyes具体Exercise的完成情况Exercise1:源代码阅读Parti:阅读code/userprog/progtest.cc,着重理解nachos执行用户程序的过程,以及该过程中与内存管理相关的要点。阅读情况:用户程序执行过程:步骤相关解释在main函数中,如果检测到传入的参数和“执行用户程序”相关,那么执行StartProcess函数(progtest.cc)在StartProcess函数中装载并运彳口一个用户程序StartProcess函数中:1.用OpenFile类打开文件OpenFile类在文件系统中te义,包括各种对文件的基本操作,如read,write。

3、实质上是包装了操作系统的底层函数。2.用AddrSpace类创建一个用户空间,并将打开的文件装载进去创建用户空间包括:1 .狄取文件头,并将大小端做适宜转换;2 .通过文件头计算出文件所需空间,包括代码段,初始化数据段,未初始化数据段,栈空间4个部分3 .通过文件所需空间计算出文件所需的虚拟页数量4 .创建用户空间的pagetable,指示了第i个虚拟页(将)对应第i个物理页5 .由于目前是最基本的【直接映射+单用户程序无切换】模式,因此此时要将所有的虚拟页中的内容写到物理页(主存)当中。3.(AddrSpace:InitRegisters()初始化用户空间中的各种寄存器,包括PC设为0,栈指

4、针移到空间底部为执行用户程序做准备!4.(AddrSpace:RestoreState()将用户的部分状态(如pagetable)装载到machine类中,准备执行事实上,仅仅是将用户空间的Pagetable(在第二步创建的)装载到machine的指针中,相当于是用户程序在machine上运行时,是通过machine的pagetable映射找至U对应内容运行的5.调用machine-Run,运行用户程序Machine-run是在mipssim.cc中定义的。其工作原理为:1 .通过OneInstruction(instr)模才以mips,将一条指令进行分割,并软件模拟执行。其中,在OneIns

5、truction函数中,通过machine-ReadMem,读取生存中当前PC值指向的地址里的指令。在ReadMem函数中,通过Translate函数对传入的虚地址做转换。在Translate函数中,如果虚地址没有找到对应的实地址转换,就会抛出异常(返回异常值)。返回的异常值在ReadMem中判断,并传入RaiseException函数中RaiseException函数会调用ExceptionHandler函数对/、同的异常做相应的处理。(以上是异常处理机制。在这里就顺便说了。)2 .调用onetick让时间前进3 .重复1,2Part2:阅读code/machine目录下的machine.h

6、(cc),translate.h(cc)文件和code/userprog目录下的exception.h(cc),理解当前Nachos系统所采用的TLB机制和地址转换机制。TLB机制和地址转换机制:相关内容简单解释TranslationEntry类(translated),包括:virtualPage,physicalPage,以及一些标志位:valid,readonly等。标识了用户空间的第i个虚拟页应该映射到主存的第j个物理页,并且这个物理页目前所处的状态。(valid?readOnly?等)TLB初始化(machine.cc构造函数):生成指定数量的TranslationEntry构成的数

7、组,并且设置均为Invalid.TLB本身就类似于Pagetable的子集,侣后卜的的映射对。TLB的使用(translate.cctranslate函数):1 .遍历TLB数组,查找是否有对应映射2 .如果有,TLB命中,直接进行物理地址转换;否贝U,TLBMISS,进入Exception处理。(目前还没有对应的处理函数)无地址转换机制:在translate.cctranslate函数中进行。1. 通过virtualaddr,计算出vpn和offset;2. 通过TLB或是直接通过Pagetable,获得vpn对应的ppn;(否则抛出异常,在异常处理函数中做处理,但目前这部分没有实现)3.

8、通过ppn和0ffset得到物理地址,将物理地址返回。无TLBmiss或是pagefault处理(exception.cc):在上一个表格中已经对异常处理是如何进入的做了介绍。但这里要补充一点:在处理完TLBmiss或是Pagefault之后,/、需要将PC+4,因为异常处理函数结束后,返回的最终位直会是OneInstruction函数的取指阶段。取指失败后,OneInstruction函数会退出,然后再用同样的PC取一次指令。而这次就能够TLBhit或者pagetablehit了。无Exercise2:TLBMISS异常处理任务:修改code/userprog目录下exception.cc中

9、的ExceptionHandler函数,使得Nachos系统可以对TLB异常进行处理(TLB异常时,Nachos系统会抛出PageFaultException,详见code/machine/machine.cc)。完成情况:关于异常处理的机理已经在Exercise1中说明了。因此能够对TLB异常进行处理,我们只要在判断传入的参数为TLBMISS的异常,并对其进行处理即可。事实上,我在实际操作的时候,TLBMISS和PAGEFAULT抛出的异常都是PageFaultException,此后再判断machine-tlb是否为空。如果为空,则执行PagefaultFunc;否则,执行TLBmissF

10、unGTLBmissFunc:步骤简单解释1.从machine的BadVAddrReg寄存器中取出发生异常的虚拟地址,并算出vpn;在RaiseException函数中,将发生异常的虚拟地址放入该寄存器的。2.扫描pagetable,寻找该vpn对应的项。目前情况,是一定可以找到的。由于目前用户程序运行的机理是:将所有segment全部与入主存中,并且全部做好了虚实映射,放在自己的PageTable中。当mechine需要加载这个用户程序时,会犹得这个pagetable。于是相当于是,mechine通过这个pagetable,可以得到用户空间所有虚地址对应的实地址。因此当TLBMISS时,查找

11、pagetable,是,定/、会Miss的。3.接下来是寻找放入TLB的位置:1)先考虑TLB中invalid的项,如果存在,写入该项;2)如果不存在invalid项,那么就涉及TLB置换算法,这在Exercise3中介绍。总之最后一B可以找到一个放置新的entry项的位置。无Exercise3:置换算法任务:为TLB机制实现至少两种置换算法,通过比较不同算法的置换次数可比较算法的优劣。完成情况:FIFO替换算法LRU替换算法1 .如果替换的是Invalid项,那么不涉及算法。2 .否则,将数组第一个项丢弃,其他项向前移动一位。新添加的项放在数组最后3 .为每个entry设立一个lru数值。当

12、TLBHIT时,HIT项的lru左移加一,其余项的lru左移;当TLBMISS时,进入异常处理函数4 .异常处理函数中,如果替换的是Invalid项,则将所有valid项(包括当前替换项)的lru值清零5 .否则,扫描TLB数组,找到Lru值最小的一项进行替换,并将所有项的lru值清零测试的用户程序将数组大小改成5的矩阵相乘:matmult。将会分配18个物理页,TLB访问次数为15000左右。(visittime/、同,是因为每次miss异常处理之后,还会再次访问该地址,因此Miss次数不同,造成visittime次数也会/、同。)测试结果FIFO:Itlbvisittimeis15534,

13、hittineis14475,hitratets6.931827LRU:1TLBvisittimeis15327#hittineis1442hitrateis0.941411结论:LRU算法略优于FIFCLExercise4:内存全局管理数据结构任务:设计并实现一个全局性的数据结构(如空闲链表、位图等)来进行内存的分配和Physpage 0fornain is allocated 4physpage 1formain is allocated.physpage 2formatn ts allocated.ph”page 3formain is allocated *physpage 4form

14、ain is allocated 4Physpage 5formain i.s a 1.located*Physpage &fornatn is allocated.physpage 7formain is allocated.physpage &formain is allocated 4physpage 9formain is allocated *thread mainstarts running.thread mainexited * * *physpage Sformain is clear.physpage 1formain is clearPhyspage 2fornain i.

15、s clear.physpage 3formatn is clear.physpage 4fornain is clear 4physpage 5formain is clear.Physpage 6formain i.s clear.physpage 7formain is clear.physpage 8formain ts clear.physpage 9formain is clear.测试结果截图:分配页开始执行用户程序回收,并记录当前内存的使用状态。完成情况:增改情况简单解释创建Machine类中,新增一个bitmap的数据结构memoryMNG,大小设置为物理页大小memoryM

16、NG的隼-个bit对应一个物理页的分配状况内存分配Addrspace.cc构造函数中,在构建用户空间的pagetable时,通过bitmap的成员函数find返回A个为0的位,将其作为空闲物理页分配。Find函数返回第一个为0的位,并将该位置1。这非常符合我们的要求。如果不存在为0的位,返回-1。因此我会用Assert来保证能够正确分配物理页。内存回收Exception.cchandler函数中,对于exit系统调用的处理函数中,通过bitmap的成员函数clear,将pagetable中的所有物理页释放,并设置该项为invalid关于在哪回收内存,这是个比较麻烦的问题。因为用户程序运行完毕之

17、后,是不会离开machine-run的for循环的,并且在调用machine-run之后的语句也不会被执行。因此,只能在exit系统调用中回收比较可行。补充:关于exit系统调用的异常处理函数其实有点麻烦,因为用户程序可以显式调用Exit,而用户程序结束之后,也会自动执彳L个exit。所以,有可能会有2个exit被执行。考虑到这个情况,需要做如下处理:1)如果bitmap已经被回收过了,就break出来。2)exit处理函数之后,PC要+4。Exercise5:多线程支持任务:目前Nachos系统的内存中同时只能存在一个线程,我们希望打破这种限制,使得Nachos系统支持多个线程同时存在于内存

18、中。完成情况:考虑:目前用户程序对mainMemory的操作是:在初始化用户空间的时候,会将mainMemory清零,并写入自己的内容。因此,每次运行用户程序,只能有一个在主存中。(主存里仅容许一个用户程序存放)如下截图:/工巳。outtheuntieaddressspace,tozerotheunitializeddatasegment/andthestacksegmentbzero(machtneridtnMemory3size);segment都是直接且一次性全部此外,目前mainMemory并没有真正实现分页,所有的写入的,如下图:主存用户程序因此,我们希望实现的目标是,将主存分页(物

19、理页)这样不同的用户程序的某些虚拟页就可以映射到某些物理页上,也将用户程序分页(虚拟页),也就可以“共存” 了,原理如下图:代码丹+效据图切总成代码鼠+蚊期E旦pages.ize;n小的若干有一一/每一份割血了fI I I I I1T代斜服+数附段(通过每个字节的虚拟地址提到对我的物理地址即可)虚地址页号.物 埋地址由号孔虚映电 址页号就是从。开的 柱后粕写 ,物理地址 页号前面已经分配 好.0按字节写入a的,不连爆,事实 上要按照实际情标注网位目,放入inmemoiy(图示的使画在真正实现的时候,是按照字节写入的,先写代码段,再写数据段。if(noffH*code+sizeo)DEBUC(1

20、aInitializingcodesegmentattsize%dnMtnoffn+code,virtualAddr,noffH.codesize);/positionofcodetobewrittenintomdinmemorytntcodepos=rioffH*code*InFtleAddr;for(tntj=e;jReodAt(machine-mai.nMenorypaddr)code_pos+);/tnFileAddrneansthepositioninthefile)if(noffH*tnttData,size0)DEBUG(1a,Initializingdatasegment/at

21、tsize%dnMtnoffH,LnitOata*vtrtualAddr,ncffH.tnttData*size);/positionofcodetobewrittentntoriai.nnemoryIntdat_pos=noffH,tnitData.inFtleAddr;for(lntj=0;j耳naffH.inttDatasize;j+)intvpn_tnp=(noffH.initData.virtuaLAddr+j)/PageSize;Intoffset_tnp=(noffH.tnttData+virtualAddr+j)%PageStze;intpaddr=pagelablevpn_t

22、np.physicalPage+PageSize+offset_tnp;executableReadAt(a(nachtnematnnenorypdddr),1,ddta_pos+);/inFtleAddrmeansthepositioninthefileprtntf(Mdn,paddr);测试的时候,在startprocess函数体中,再新创建一个线程,并让这个线程装载一个用户程序,且抢占式执行。因此我们会看到:主函数的用户程序分配完页表后,还没开始执行,另一个线程的用户程序就分配页表,并执行了。当这个线程执行完毕之后,才轮到主函数的用户程序执行。这就说明了,可以多线程同时存在于主存当中。此

23、外,还有一个需要说明的点:线程切换是如何影响用户程序切换的?在scheduler-run函数的ifdefuser_program的宏定义语句中,包括以下两个函数:函数简单解释Switch之前currentThread-SaveUserState()将所有用户程序的寄存器,从machine的寄存器数组拷贝到装载线程的寄存器数组中,包才PC寄存器等。currentThread-space-SaveState()目前函数体为空。改与:将machine的TLB数组全部设置为invalid。(因为线程切换后,TLB中的内容全部失效)Switch之后currentThread-RestoreUserSta

24、te()与对应,将所有用户程序的寄存器,从装载线程的寄存器数组拷贝到machine的寄存器数组中,相当于恢复上卜文环境。currentThread-space-RestoreState()与对应,将用户空间的Pagetable装载到machine上。总结:通过寄存器数组以及pagetable的转换,实现了/、同用户程序的切换。测试截图:(测试函数:主线程和第二个线程均运行一个只有空函数体的用户程序。wwubu(itu:/OS/nachos-3.4/code/userprogi$ttdisGj,priority=lmainthreadiscreatedr/nachos-x.test/haItph

25、yspage2formainisallocated,physpag3formainis匚口twd.physp曰ge4fornatruisall。匚口ted,physpage5fornalnisallocatedPphyspge(5forftatnisallocated-physpage7fortwinisallocated.physpage8formainisallocated.physpage9fornatnisallocated.physpageIBforsecandthreadtsphyspage11forsecondthreadtsph/spage12for&ecariidthread

26、isphyspage13forsecandthreadisphyspage14forsecondthreadisphyspage15forsecondthreadisphyspage16forsecondthreadisphyspage17forsecondthreadisphyspageisforsecondthreadisphyspage19forsecondthreadismainismiainisphysphyspagepageforforallocated.allocated.主线程中的用户程序分配页allorated.allocdted.aillQcatedu.allacatedu

27、.allocateda.allocated,allacated.allocated.allocated.iallocatedi.thread)secondthreadstartsrunning.,threadsecondthreadexited.,.第二个线程中的用户程序分配页第二个线程中的用户程序开始运行physphysphyipMpWphyspagepagepagepagepagepagepage口aqe10forforforforfarforforsecondsecondsecondsecondgiecoriidsecondsecoHidthreadthreadthreadthreadt

28、hreadthreadthreadFor6电白ndthreadIsclear,clear,clear+clear+clear+clear+clear+clear、第二个线程中的用户程序结束运行第二个线程中的用户程序释放页physpagephyspagephyspagetid=lhas17forsecond18forsecond19forsecondfinished*threadisthreadisthreadisclear,clear,clear,nawinthreadmain线程切换threadnatnthreddi*iatnstartsrunning.exited*主线程中的用户程序开始运

29、行physphysphysphysphysphysphysphysphysphyspagepagepagepagepagepagepagepagepagepageforforforforforforforforforfornainnatnmainnainmainmainnainmainnainmainisclear.clear.clear*clear,clear,clear-clear,clear*clear.clear,主线程中的用户程序结束运行主线程中的用户程序释放页TLBVisit51,hitrateis0.S79316MachinehaltinglTicks:total76fidle0

30、,systen391user46DiskI/0:reads9,writes6ConsoleI/O:reads*writes0Paging:faults6NetworkI/O:packetsreceived%sentGCleaningup*.wwubuntu:T0S/nmc:hg-3.4/3de/u5pQg5Exercise6:缺页中断处理任务:基于TLB机制的异常处理和页面替换算法的实践,实现缺页中断处理(注意!TLB机制的异常处理是将内存中已有的页面调入TLB,而此处的缺页中断处理则是从磁盘中调入新的页面到内存)、页面替换算法等。Exercise7:Lazy-loading任务:我们已经知道

31、,Nachos系统为用户程序分配内存必须在用户程序载入内存时一次性完成,故此,系统能够运行的用户程序的大小被严格限制在4KB以下。请实现Lazy-loading的内存分配算法,使得当且仅当程序运行过程中缺页中断发生时,才会将所需的页面从磁盘调入内存。Challenge2:倒排页表为了节省物理内任务:多级页表的缺陷在于页表的大小与虚拟地址空间的大小成正比,存在页表存储上的消耗,请在Nachos系统中实现倒排页表。完成情况:Exercise6,Exercise7Challenge超是一起完成的。分析:1 .缺页中断如何发生?(Exercise6对于目前的虚拟内存系统来说,缺页中断是不会发生的。因为

32、无论是单线程还是多线程,在用户程序运行之前,就已经将所有内容拷贝到了主存当中,pagetable也做好了全部映射。因此缺页中断要想发生,就不能在一开始就将全部内容拷贝到主存当中。而这恰恰是Exercise7要做的。2 .缺页中断发生时,需要做什么?(Exercise7核心任务是将发生缺页中断的虚拟地址所在的虚拟页拷贝到某一张物理页当中。因此,需要:1)找到该虚拟页;2)确定合适拷贝的物理页(必要时候需要考虑脏页写出的问题)。3 .缺页中断如何支持多线程用户程序的交替运行?(Challenge2虽说每个用户空间都维护一张pagetable也是可行的,但如果是多线程用户程序运行,使用倒排页表显然更

33、加节约空间。在倒排页表中,记录了第i个物理页对应的虚拟页以及进程id,于是缺页中断(问题2)发生时,只需通过倒排页表找到对应线程进行页表内容的写入、写出即可。改动:改动简单解释增改变量1.取消用户空间的pagetable,维护machine类中的物理页大小的倒排贝表数组倒排底表的每一项包括:虚拟页号,进程id,一些标志位(如dirty位)第i项表示第i个物理页的情况。2.Thread类中新增char*变量,用于记录用户程序文件的文件名。在Progtest.cc中,初始化用户程序空间的地方,赋值。3.Thread尘中新增int变量,用于记录用户程序文件的codesegment的起始位直。在add

34、rspace.cc中,addrspace构造函数的是偶,赋值。线程运行流程中虚实地址转换(translate.cc)(取消了TLB!)事实上,TLB可以使用,但太麻烦了。1 .将虚拟地址算出所在的虚拟页vpn2 .对比倒排贝表巾,是否启某项满足:valid;虚拟页号=vpn;线程口=当前线程Id。3 .如果有,表小pagehit,可以计算出物理地址从而访问土存4 .如果没有,抛出Pagefault异常。Pagefault处理函数(exception.c1.使用Exercise4中与的内存管理器,调用bitmap的find函数,寻找是否用空闲的物理页面由于bitmap和倒排贝表此时是,对应的,即

35、:如果bitmap某位为0,那么证明该物理页未分配,那么倒排页表中该项就一定没有内容。2.如果有,1)修改该物理贝囿对应的倒排贝表项,填写“虚拟页号”和“线程ID”项2)设置标志位3)通过当前线程指针找到用户程序文件,把虚拟页面写入主存Thread类中新增了用户程序文件的名称以及codesegment的偏移量。可以正确拷贝一张虚拟页的内容进入主存3.如果没有,根据页面替换算法,选择倒排贝表中的项进行替换:1)判断dirty位,如果是脏页,通过该项找到对应的线程,从而认得用户程1手文件,将对应的页面写回2)执行步骤2.这里有两个问题:1)脏页写回:事实上应该采用交换空间,暂时存放换出主存的贝囿的

36、;但由于维护起来过于麻烦,贪图方便,就将脏页直接写回文件了。2)通过倒排页表中的线程id找到对应线程:在LAB1中实现了一个存放所有线程的线程池,池内的线程Id和在池内的下标是对应的。线程切换Addrspace.cc中,restorestate()函数中,载入用户程序的pagetable的两条语句需要注释掉不冉需要维护用户空间的pagetable线程结束(exceptions。Exit系统调用中,需要将原来对Pagetable的操作转移到对倒排页表的操作。将占用的物理页归还(bitmap对应位直清0),将倒排页表对应项清空无页面替换算法LRU替换算法:1. Translate.cc中,倒排底表

37、命中一次,将命中项的Lru左移加一,其余项的Lru左移2. Pagefault处理函数中,对新添表项处理完毕之后,都需要将所有的倒排页表的lru清0Lru是l个Int型数值,在贝间替换的时候,选取最小的一项进行替换。并且每次pagefault发生时,需要将所有项的Lru从0开始计算,防止某个页面反复被替换。nowinthreadmainthreadmainpagefaulthappenedat768nowtnthreadsecondthreadnowtnthreadnatnthreadmainpagefaulthappenedat640nowinthreadsecondthreadthread

38、secondthreadpagefaulthappenedat588nowinthreadmainthreadmainpagefaulthappenedat892nowinthreadsecondthreadthreadsecondthreadpagefaulthappenedat896nowinthreadmainnowinthreadsecondthreadthreadsecondthreadpagefaulthappenedat768nowtnthreadmatrithreadmainpagefaulthappenedat876nowinthreadsecondthreadthreads

39、econdthreadpagefaulthappenedat768threadsecondthreadpagefaulthappenedat640threadsecondthreadpagefaulthappenedat768nowinthreadmainnowinthreadsecondthreadnowtnthreadmainnoMinthreadsecondthread于是,到目前为止,我们已经可以在Nachos系统中多线程同时(交替上下cpu)运行用户程序了!并且是支持lazy-loading的(三三)/测试截图:(主线程和第二个线程均运行Matmult,该程序自身需要的物理页就已经超

40、出了主存。因此不仅仅是线程切换会造成pagefault,同个线程本身也会需要pagefault来更替内容)测试截图:程序执行完毕退出的时候,需要交还分配的物理页。这里看起来两个线程各拿了一半。这里看起来似乎发生了替换页颠簸。threadsecondthreadexited.,physpage2forsecondthreadisclear.physpage3forsecondthreadisclear*physpage6forsecondthreadisclear*physpage9forsecondthreadisclear.physpage1forsecondthreadisclear.ph

41、yspage16forsecondthreadisclear4physpage18forsecondthreadisClear.physpage19forsecondthreadisclear.physpage21forsecondthreadisclear*physpage23forsecondthreadisclear.physpage24forsecondthreadisclear*physpage25forsecondthreadisclear.physpage27forsecondthreadisclear.physpage30forsecondthreadisclear*physp

42、age31forsecondthreadistidalhasfinished,noMinthreadmainthreadmainexited.,.physpage0formainIsclear,physpage1formainisclear*physpage4formatnisclear*clear4physpage7formainisclear4physpage8fornatnIsclear.physpage11formainisclear*physpage12formainisclear.physpage13formainisclear.physpage14formainisclear*p

43、hyspage15formaintsclear.physpage17formainisclear.physpage20formainisclear*physpage22formaintsclear.physpage26formaintsclear.physpage28formainisclear*physpage29formainisclear.threadmainpagefaultMachinehalting!happenedat40Ticks:total184224,Idle,system1772,user166504DiskI/O:readswrites0ConsoleI/O:reads

44、0,Paging:faults6writes0NetworkI/O:packetsCleaningup.received0,sent0三:遇到的困难以及解决方法困难1:在一开始做LAB的时候,无法让TLB生效即使在makefile里使用了DUSE_TL弛不管用,为了使用TLB,只能对machine初始化函数中做了一些注释,让machine一定使用TLR困难2:用户程序的运行过程,包括线程切换等这是为了做lab必须了解清楚的。因此只能很认真地研究了不少时间。困难3:换出的脏页往哪放?交换空间是个正确选择,但是实现起来有些麻烦因此最后采取“直接写回文件”。但应该是不正确的。四:收获及感想这次lab

45、的完成时间是三周,事实上我也确实断断续续写了快三周才写完。首先研究清楚机制就花了不少时间,其次要将Nachos系统的虚拟内存和真实系统的虚拟内存做比较,搞清楚二者之间的相同和相异的点,才能找到折中又不失优雅的方式完成每一个Exercise。但话说回来,感觉收获还是很大的。这套系统有很多设计巧妙的小细节,一旦注意到了就会觉得是一个值得学习的点,对于将来一定是有着潜在益处的。这次Lab我和我们组的组员陈震鹏探讨了不少时间,感觉讨论的力量还是强大的。两个臭皮匠发挥了半个诸葛亮的作用五:对课程的意见和建议感觉实验要求里什么有用的信息都没有,全部都靠自己摸索完成的lab。希望下次布置lab(尤其是这种比较繁琐的)能够给予更多的一些基本提示。(当然事实上这些提示也只是加快我们完成lab的速度,靠自己摸索也是能够实现的:)所以仅仅是从一个学生角度的建议啦)六:参考文献组员陈震鹏的一起讨论大神王维梓的请教【下载本文档,可以自由复制内容或自由编辑修改内容,更多精彩文章,期待你的好评和关注,我将一如既往为您服务】

展开阅读全文
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!