pae选项

[TOC]

32位系统通过物理地址扩展可以使用超过4Gib的物理内存,怎么做到的呢?

众所周知一个32位进程的虚拟地址最多能表示2^20个页,用虚拟地址里剩下的12bits表示4k的偏移量。其能表示的内存大小上限为2^20*2^12=2^32byte=4Gib

如实际物理内存恰好等于进程中能寻址的虚拟内存,即物理内存<=4Gib(2^32)。偏移2^12(4k),需要2^20个页框表示。相应的页表项里用来寻址的部分(pfn)应该有20bits才能表示完对应到物理内存的2^20个页框,和32位虚拟地址空间里最多能表示的页个数相同,即虚拟内存刚好可映射到整个物理内存。

PAE模式如何支持大于32GB的物理内存?


**
**PAE模式下,系统中的进程任意时刻还是只能访问4GB的地址空间,这是虚拟地址宽度所限,但是考虑到一般的页表项结构,低12位做各种标志,高20位作为物理页框号,这样满打满算也就可以定位2^20=1M个物理页面,也就是在普通模式下无论如何最高只能支持4GB物理内存。

PAE模式下就不同了,其稍微改变了下页表结构,把一个32位的虚拟地址分成4个部分:
0-11:页内偏移

12-20:页表(Page Table)

21-29:页表目录表(Page Table Directory)

30-31:页目录指针表(Page Directory Pointer Table)

可以看到,这里PAE的分页把页表项做成了8个字节,即64Bit,除去低12位做标志,还有52位可以用作寻址物理页框,这正是PAE模式的核心。

细心的人可能会发现,即使如此,虚拟地址一共就32位,你2^22^92^9*4KB仍然是4GB 呀,怎么说就支持大于4GB的呢?没错,这也正是我开始疑惑的地方。但是人家根本没把思想放在这方面,这也正是前面提到任意时刻,一个进程最高只能使用4GB的原因。重要的在于操作系统是多任务的,如果是在普通模式下,我现在有8GB的物理内存,而当前系统运行5个进程和系统进程,如果每个进程当前都需要1GB的物理内存,则在此模式下使行不通的,这6个进程只能平分8GB中的4GB,其他的只能通过不停的换入换出来实现。

而在支持PAE模式的情况下就不同了,上面6个进程均可分到1GB物理内存,并且在需要的时候还可以增加。这就是PAE带来的好处。

话说说到这里,可能还有人不明白。分页机制中有个重要的概念就是物理页框号,页表能够层层递进正是在页表项中记录了物理页框号。物理页框号可是全局的,即在整个系统中不会有重复的物理页框。在普通模式下,只有20位用于物理页框号,那么最高也就是支持2^20=1M个页,即4GB物理内存。其他的有再多的内存寻址不到啊!

在PAE模式下,使用36根地址线,最大可以索引到64GB的物理内存。由于页表项中有52位可以作为页框号,所以其可以定位更多的物理页框。即使碍于虚拟地址宽度所限,一个进程只能访问4GB空间,但是放大格局。站在系统的角度,则是在其他的进程需要的时候,可以减少换出内存的次数,这是后备力量的加强!!

作者:玄成
链接:https://www.nowcoder.com/discuss/728283?source_id=profile_create_nctrack&channel=-1
来源:牛客网

给扑克牌洗牌,怎么做好一点?1/54来挑选,如果有被拿走的呢,只能再循环,或者变成1/n来挑,n是剩余没有洗牌的数量
了解过游戏架构吗?说了唯一知道的c/s和p2p
简单问了一下实习和项目,json库有没有和别人比较过,发现我抄的这个json库就是人家部门的人写的,哭了
问了一下计网,https的作用是什么,TCP有什么特点介绍一下,说了面向字节流、可靠性、耗时会略久这些
CPP问题,比如A作为父类被bcd继承,只有a有虚函数,问有几个虚函数表,答1个
说一下了解的cpp特性,说了一下11和14的,override、final、lambda这些,答得不全,问智能指针知道吗,说知道,但是没用过
类方法的this指针怎么来的,作为第一个参数推入栈中,推入栈太慢了,有方法优化吗。先是说全局变量,然后又说把方法改成内联函数,最后说用asm内联汇编,还有c语言里的register关键字,不知道对不对。
用memset把内存区域清零,说一下了解。先是说了对二级指针这样做没用,然后说写法不对可能只清理前8个字节,然后又说看过技术贴,for循环和memset效率差别不大。
64位机和32位机有什么差别?数据类型大小不一样,寄存器64位机有reextended的寄存器,进程内存大小不一样,机器指令不知道会不会一样。
64位机中的32位区域,内存大小会是多少?这个真不知道,只能硬着头皮说一下我了解过PAE技术,然后说了一下PAE
说一下你了解的协程。只了解Go的协程,其他语言的不知道,然后说了一下Go的GMP模型,系统级线程和用户级协程这些
几千万级别的数据,需要用哈希来存储和查询,不考虑更新和删除,怎么做。这个也不太会,只能硬头皮说几句了。如果哈希值是数字域,考虑开一个很大的数组来存储,或者bitmap表示是否存在。如果是字符串,考虑用字典树来存储。
然后几千万级别很容易哈希冲突,查询起来很难做到绝对O(1),哈希冲突我会用链表法来存储。
然后问了一下北京腾讯实习的东西,遇到的困难(trpc不会用!),事情是怎么做的
因为实习有用到es数据库,问了一下es中index的概念和用途。我答:es 7.x之前,index类似于MySQL的database,可以存不同结构的数据,type才类似具体table。7.x之后index就是table了。
es查询默认返回多少条?不知道,我们用的都指明了条数,只知道上限。index可以存不同结构的数据吗?不行吧,顶多有可以为0的字段。
说一下linux下的io模型,同步非同步异步多路复用说了4个,一共六个记不全了。然后多路复用说一下select和epoll的差别,用户态系统态拷贝,轮询和回调,数组和红黑树,select有上限这些说一下。然后问少量数据下,epoll和select表现怎么样,应该持平(现在感觉应该是select快)