浅谈限制内存容量的屏障

浅谈限制内存容量的屏障
文/Sobereva @北京科音   2009-Feb-2


PS:有很多人有误区,甚至包括一些计算机老师,比如认为32bit平台因为2^32=4G所以认为不能使用超过4G内存,然而接受这样的观点后很多人会对为何使用4G内存在系统中只显示3.25G有所疑问。网上也有很多相关文章专门谈这个问题,但是其中有不少错误的认识,而且条理不清。故撰此文,以尽可能简单的解释来清楚地解释这些问题。



程序使用内存到底能用到多大,跟CPU、内存控制器、操作系统、程序、主板都有关,其中支持内存最小的一个就是瓶颈。

CPU:能用到多大和CPU的位数没有直接关系。因为CPU的位数,即通用寄存器的宽度并不等于地址总线的宽度。比如8086,16bit通用寄存器但地址总线是20bit(=1MB);P6架构虽然是32bit的,但其外部地址总线为36bit,寻址范围已经到了2^36=64G了;x86-64的AMD CPU,内存寻址范围是48bit(256T),没有达到64bit,虽然理论上能到但实际上没能实现2^64的寻址范围。所以一般来说CPU不是瓶颈,注意若在32bit系统下实现36bit寻址需要通过PAE(Physical Address Extension)。

主板:取决于主板有多少槽和芯片组最大支持容量。

内存控制器:如果是K8及之后的,因为集成内存控制器,所以是CPU负责,这一般没有问题,可达48bit。而对于intel CPU由芯片组负责,老的芯片组比如945就只能支持32bit寻址即4G,这就需要新的芯片组,如965系列寻址空间达到36bit,但实际最大支持8G。服务器芯片组一般实际支持得比较大,寻址空间一般为36/38bit。

操作系统:windows操作系统如果是64bit的,至少支持8G,无需PAE,目前支持容量最高的数据中心版本可支持2T,用的是44bit寻址(16T)但没有全开放。如果是32bit版本,XP和Vista任何版本皆最多4G,因为都不支持PAE。若用server版本,都支持PAE,可以超过4G,最强Datacenter版可达128G。

程序:对于32bit windows系统,无论真正可用内存有多大,用户模式的程序最大只能分配2G虚拟内存,其它部分由系统核心调用。用了4GT即4GB内存调优技术,可分配最大3G,仅server版支持,启动时加/3GB即可。如果程序设计时使用AWE API集而且系统支持PAE,寻址范围可以扩至64GB。另外驱动也必须合适,比如一些老驱动程序在大内存下不能正常工作。在64bit windows下,用户模式的程序直接就可以访问8T空间。

总之,若在32bit平台下使程序能够调用超过4G内存,需要windows server版系统+合适的芯片组+槽多的主板+合适的程序。如果只有普通的32bit程序,大内存至少可以减少不同程序虚拟内存间的抢占,让每个程序都获得尽可能大的虚拟内存,尽管上限仍是2G。


另一个问题:4G内存时,发现可见内存被吞掉750MB或者更多,是因为一些设备固定占据挨着并且低于4GB位置的一段空间,称为MMIO(PCI内存占其中很大部分),这是内存控制器将这些设备映射到这个地址实现的,好处是系统可以方便快速地通过内存地址来访问这些设备,但原来在这个部位的物理内存就访问不到了,很浪费,也叫memory hole,尤其是GPU越多占得越多。解决方法就是用内存重映射(Memory Remapping),内存控制器把这个部位的内存地址映射到4G位置后面的一段空间,然后将这样转化过的地址告诉CPU,这样CPU用大于FFFFFFFF的地址就可以访问到原本被MMIO覆盖的内存空间,就不会浪费了。

使用内存重映射,若是32bit操作系统的话必须支持PAE,否则高于4G的映射空间还是访问不了,不同操作系统对重映射支持也不同,server版比较好。芯片组必须支持重映射并且开启(对于A64及以后的是在CPU内的内存控制器实现),至少680i、955X、965系列及以上或者是服务器芯片组,如果主板BIOS没有相应选项而且默认是关闭的就不行。

对于XP,系统属性-常规下面显示的就是此时相对于操作系统全部能使用或者说可见的内存空间,不包括MMIO部分。注意对于Vista SP1,插了多少内存就显示多大,即使实际上根本不能全部利用。