注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

Mihooke's blog

IT之恋

 
 
 

日志

 
 

《深入理解计算机系统》笔记(五)  

2014-09-26 15:49:26|  分类: 学习录 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |


九、虚拟存储器(VM

1、CPU通过生成一个虚拟地址来访问内存,这个虚拟地址在被送到存储器之前先转换成物理地址。CPU上的MMU存放虚拟地址。

虚拟存储器的基本思想是,允许每个数据对象有多个独立的地址,其中每个地址都选自一个不同的地址空间。主存中的每个字节都有一个选自虚拟地址空间的虚拟地址和选自物理地址空间的物理地址。

2、操作系统为每个进程提供了一个独立的页表。多个虚拟页面可以映射到同一个共享物理页面上。

3、VM被分割为固定大小的虚拟页(VP),每个虚拟页面有三个子集:未分配的、缓存的、未缓存的。虚拟页存储在磁盘上,物理页缓存在DRAM中。虚拟页中缓存的部分则映射到物理页中。


4 页表将虚拟页映射到物理页,页表由一个有效位和一个n位地址字段组成的。有效位表明该虚拟页是否被缓存在DRAM中,虚拟页中缓存的页就是缓存在页表中(DRAM),未缓存的页已经分配,但是还没被缓存。2014年09月26日 - mihooke - mihooke的博客

5、如上图,如果CPU读包含在VP2中的字,因为已经缓存在DRAM中了,并且设置了有效位,因此对这个引用就会命中。不命中称为缺页。当读VP3中的字时,由于VP3不在缓存中,缺页异常就会调用内核中的缺页异常处理程序,会选择一个牺牲页,那就是牺牲VP4了,内核会修改它并放回磁盘中,结果是VP4不在缓存中了。然后,VP3会被缓存到物理内存中,之后就可以正常处理了。

不过在现代系统里,不仅仅是设置有效位了,而是对有效位进行了扩展,从而对缓存字进行了保护措施。比如,设置3个许可位:SUPREADWRITESUP代表进程是否必须运行在内核模式才能访问该页;READ代表只读;WRITE代表写权限。

6、实际系统是为每个进程分配一个页表的,也就是一个独立的虚拟地址空间,这样多个虚拟页面时可以映射到同一共享物理地址的。

7、将一组连续的虚拟页映射到任意一个文件中的任意位置的表示法叫做存储器映射

每个进程都是由自己私有区域和共享区域来维护的。一方面,每个进程有自己私有的代码、数据、堆、栈,是不和其他进程共享的,这时候系统创建页表,将相应的虚拟页映射到不同的物理页;另一方面,每个进程必须调用相同的系统内核代码,C程序也要调用C标准库的中程序,这时候系统将多个进程共享这部分代码的一个拷贝。

8、每次CPU产生一个虚拟地址,MMU(内存管理单元)就必须查阅一个PTE(页表有效位),以便将虚拟地址翻译为物理地址。如果PTE正好缓存在L1 cache中,那么开销就下降若干个周期,然而系统就是为了减少这样的开销在MMU中包括了一个关于PTE的小的缓存,叫TLB(翻译后备缓冲器)。 

9Linux虚拟存储器系统

2014年09月26日 - mihooke - mihooke的博客

 Linux内核为系统中的每个进程维护一个单独的任务结构task_struct,结构中的元素包含指向内核运行该进程所需有的所有信息。其中的一个条目指向mm_struct,它描述了虚拟存储器的当前状态,其中有重要的两个字段pdgmmappdg指向第一级页表的基址,mmap指向一个vm_area_structs的链表。

10、虚拟存储映射:共享区域和私有区域,共享区域是多个进程将共享对象映射到自己的虚拟存储器一个区域中,物理存储器中只是存放了共享对象的一个拷贝。私有区域,用了写时拷贝技术,同样地,多个进程将共享对象映射到自己的虚拟内存中的不同区域,共享这个对象的同一个物理拷贝,但是当有进程试图去对私有区域的某个页面进行写操作时,就会调用故障处理程序去保护,并在物理内存中创建这个页面的一个拷贝,更新页表条目指向新的拷贝,然后恢复这个页面的可写权限。

10.1fork函数,当前进程调用fork函数时,内核为子进程创建各种数据结构,并为它分配一个唯一的PID,还创建了父进程的mm_struct、区域结构和页表的原样拷贝来构建虚拟存储器。两个进程的每个页面都标记位只读,并将两个进程的每个区域结构都标记为私有的写时拷贝;当fork在子进程中返回时,子进程的虚拟存储器和调用fork时的虚拟存储器相同,当父子进程其中一个进行写操作时,写时拷贝机制就会创建新页面。

10.2execve函数,如何来加载和执行程序的。首先,删除当前进程虚拟地址用户部分中已存在的区域结构;为新程序的文本、数据、bss和栈区创建按新的区域结构(映射私有区域);与共享对象链接(映射共享区域);设置当前进程上下文中的程序计数器。

10.3mmap函数,来创建新的虚拟存储器区域,并将对象映射到这些区域中。

#include <unistd.h>

#include <sys/mman.h>

void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);//若成功,则指向映射区域的指针

Mmap函数要求内核创建一个新的虚拟存储器区域,从start地址开始,并将文件描述符fd指定的对象的一个连续的片映射到此区域,连续的对象片大小问length字节,从距文件开始处偏移值为offset字节开始。这里start一般定义为NULLprot表示新映射虚拟区域的访问权限,值有PROT_EXECPROT_READPROT_WRITEPROT_NONEflags映射对象类型组成,值有MAP_ANON(匿名对象)、MAP_PRIVATE(私有对象)、MAP_SHARED(共享对象)。


11、动态存储器分配问题,是在堆区域中分配的,有两个互相冲突的目标:最大化的吞吐率和最大化的存储器利用率。分配器设计就是要从两者之间找一个平衡值。

一个堆块是由一个字的头部(也就是4×8个位)、有效载荷和一些额外的填充组成的。

在分配的时候,根据对齐要求,分配块的大小。比如,根据双字对齐要求,那么每个块的大小都必须是双字(8字节),即使请求分配1个字节,也要分配两字的块,一个字作头,另一个字维持对齐要求。

  评论这张
 
阅读(28)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017