为什么Windows为其系统地址空间预留1Gb(或2 Gb)?
这是一个已知的事实,Windows应用程序通常在32位系统上具有2Gb的私有空间。该空间可以通过/ 3Gb开关扩展到3Gb。
操作系统保留了4Gb的剩余部分。 我的问题是为什么? 在内核模式下运行的代码(即设备驱动程序代码)具有自己的地址空间。为什么在独占的4Gb地址空间之上,操作系统仍然希望保留每个用户模式进程的2Gb? 我以为原因是用户模式和内核模式之间的转换。例如,调用NtWriteFile将需要内核调度程序的地址(因此为什么系统在每个应用程序中保留2Gb)。但是,使用SYSENTER,系统服务号码不足以让内核模式的代码知道哪个功能/服务被调用? 如果你能澄清一下,为什么操作系统对每个用户模式进程采取2Gb(或1Gb)这么重要,我会感激的。 谢谢。
两个不同的用户进程具有不同的虚拟地址空间。因为虚拟的物理地址映射是不同的,所以当将上下文从一个用户进程切换到另一个用户进程时,
TLB高速缓存无效。这是非常昂贵的,因为没有在TLB中缓存的地址,任何内存访问将导致
PTE的故障和散步。
Syscalls涉及两个上下文切换:用户→内核,然后是内核→用户。为了加快速度,通常保留最高的1GB或2GB虚拟地址空间供内核使用。因为虚拟地址空间在这些上下文切换中不会改变,所以不需要TLB刷新。这是由每个PTE中的用户/管理员位启用的,这确保内核存储器仅在内核空间中可访问;即使页表相同,用户空间也无法访问。 如果有两个单独的TLB的硬件支持,一个专门用于内核使用,那么这个优化将不再有用。但是,如果您有足够的空间来投入使用,那么制作一个更大的TLB可能更有价值。 Linux on x86曾经支持一种称为“4G / 4G分割”的模式。在这种模式下,用户空间可以完全访问整个4GB的虚拟地址空间,内核还具有完整的4GB虚拟地址空间。如上所述,成本是每个系统调用需要一个TLB刷新,以及更复杂的例程以在用户和内核内存之间复制数据。这一点已经被测量到达30%的性能损失。 时间已经改变,因为这个问题最初被提出和回答:64位操作系统现在更加普遍。在x86-64上的当前操作系统中,用户程序允许从0到247-1(0-128TB)的虚拟地址,而内核永久驻留在从247×(217-1)到264-1(或从 – 247到-1,如果将地址视为有符号整数)。 如果您在64位Windows上运行32位可执行文件,会发生什么?您会认为所有虚拟地址从0到232(0-4GB)将很容易可用,但是为了避免在现有程序中显示错误,32位可执行文件仍然限制在0-2GB,除非它们重新编译为/ LARGEADDRESSAWARE 。对于那些,他们可以访问0-4GB。 (这不是一个新的标志;同样适用于运行/ 3GB开关的32位Windows内核,它将默认的2G / 2G用户/内核分裂更改为3G / 1G,尽管3-4GB仍然会出现的范围。) 可能有什么种类的错误?例如,假设您正在实现快速排序,并且有两个指针,a和b指向数组的开头和结尾。如果用(ab)/ 2选择中间作为枢轴,只要这两个地址都低于2GB,它就可以工作,但是如果它们都在上面,那么加法将会遇到整数溢出,结果将在阵列。 (正确的表达式是a(b-a)/ 2)) 除此之外,32位Linux与其默认的3G / 1G用户/内核拆分,历来是运行程序,其堆栈位于2-3GB范围内,因此任何此类编程错误都可能会被快速刷新。 64位Linux提供32位程序访问0-4GB。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- windows-server-2008 – 无法从运行Windows Server 2008 R2
- windows-server-2008 – 为什么我不能ping我的服务器?
- iis – 垃圾箱文件夹中的奇怪的’`’.dll文件,ASP.Net MVC
- windows – 为什么要打开一个产生大量线程的TOpenDialog?
- Windows系统里Oracle 11g R2 Client(64bit)的下载与安装
- windows-xp – 如何找出windows exe使用的库?
- Windows – 如何以vbs的身份运行vbs?
- Windows Phone 8.1和Windows Phone Silverlight 8.1之间的区
- Windows勒索病毒席卷全球:全系列补丁下载及解决办法(内附补
- windows-server-2003 – 从目录服务还原模式中降级2003 DC