如何在32位PAE启用的Linux应用程序中使用超过3GB的进程内存?

3
PAE(物理地址扩展)是在1994年引入CPU中的。这使得32位处理器可以访问64 GB的内存,而不是4 GB。Linux内核从2.3.23开始提供对此的支持。假设我正在引导其中之一的内核,并想编写一个C应用程序来访问超过3 GB的内存(为什么是3 GB?请看这里)。
我该如何访问超过3 GB的内存?显然,最好的解决方案在大多数情况下是简单地以64位模式引导,但我的问题严格限于如何在运行在启用PAE的32位内核上的应用程序中利用4 GB以上的物理内存。

如何编写一个能够访问超过3GB RAM的C应用程序?这个问题适合在这里提出! - Aaron Digulla
6个回答

9
只要你使用32位,每个进程都将受到内核构建的虚拟内存分割(2GB、3GB或者如果您有打过4GB / 4GB分割补丁的内核则为4GB)的限制,因此您不能直接做到。
让进程使用更多数据并仍然保留在RAM中的最简单方法之一是创建shmfs,然后将您的数据存储在该文件系统的文件中,并使用普通的seek/read/write基元进行访问,或者使用mmap逐个将它们映射到内存中(这与执行自己的分页基本相当)。但无论您做什么,都需要比使用前3GB更多的工作。

你回答了一个不同的问题。"[M]我的问题严格来说是关于如何在运行在启用PAE的32位内核上的应用程序中利用4 GB以上物理内存。" 你的答案是关于虚拟内存分割和虚拟内存限制,而问题是关于物理内存的。 - David Schwartz

6

或者您可以启动尽可能多的memcached实例,直到所有物理内存都被映射。每个memcached实例在32位机器上可以提供3GiB的可用空间。

然后通过API和语言绑定访问memcached中的内存块。根据应用程序的不同,它可能几乎与直接在64位平台上工作一样快。对于某些应用程序,您还可以获得创建可扩展程序的额外好处。很少有主板处理超过64GiB RAM,但使用memcached,您可以轻松访问尽可能多的RAM。

请注意,这种方法当然也适用于Windows或任何可以运行memcached的平台。


1
+1 因为这是解决问题的一种新颖方法!非常棒! - PP.

3
在Unix上,访问超过32位可寻址内存的一种方式是使用mmap / munmap。如果/当您想要访问未使用的内存子集时,这种方法可以使用。有点像手动分页。另一种(更简单)方法是通过在多个进程中使用不同的内存子集来隐式利用内存(如果您的代码具有多进程架构)。
mmap方法本质上与 commodore 128 程序员用于银行切换的技巧相同。在这些后 commodore-64 的日子里,由于64位支持非常普遍,甚至没有思考的好理由;)
我曾经有一个有趣的经历,数年前从我们的产品中删除了所有丑陋的PAE代码。

2
谢谢您注意到了Commodore 64和128时代的情况。这本身就对我有一分的价值。 :) - ChrisInEdmonton

3

PAE是硬件地址总线的扩展,需要进行一些页面表修改以处理它。它并不改变指针仍然是32位的事实,这限制了单个进程的地址空间为4G。老实说,在现代世界中,编写需要超过2G(Windows)或3G(Linux)地址空间的应用程序的正确方法是简单地针对64位平台。


1
真的,但在Windows和Linux上都有访问额外内存的方法。当然,这些方法可能并不值得付出努力。 - ChrisInEdmonton

2

指针不能指向大于4G的地址空间,因此需要使用许多技巧。

通过使用mmap将地址空间块在不同的物理页面之间切换应该是可能的;您可以使用mmap将大文件的位映射到内存中,任何时候都可以通过调用另一个mmap来更改文件中的偏移量(以OS页大小的倍数)来更改映射。

但是这是一种非常恶劣的技术,应该避免使用。您打算使用内存做什么?肯定有更简单的方法吧?


是的,更简单的方法是直接启动64位内核。我预计任何解决方案都涉及恶意黑客攻击,我只是对它有多恶心感兴趣。 - ChrisInEdmonton
这真的取决于您的使用情况。如果您将RAM用作光荣的磁盘缓存,那么可以根据需要映射块,但是它会创建大量开销,其中mmap将需要处理页表等,即使所需页面已经映射到RAM中。如果您正在使用线程,则此方法也会崩溃,因为它们具有共享地址空间,因此mmap基本上是不安全的,除非进行过多的锁定,这可能会使其效率极低。 - MarkR

0
显然,在大多数情况下,最好的解决方案是直接以64位模式启动,但我的问题严格来说是关于如何在运行在PAE启用的32位内核上的应用程序中利用4 GB以上物理内存。
你不需要做任何特殊的事情。只有内核需要寻址物理内存,并且使用PAE,它知道如何寻址4 GB以上的物理内存。应用程序将自动使用4 GB以上的内存,而且没有任何问题。

这与所有其他答案以及我在不同问题中阅读的几个相关答案相矛盾。您能否引用您的答案?您很可能是正确的。 - ChrisInEdmonton
@ChrisInEdmonton 如果不允许内核访问4GB以上的物理内存,你认为PAE有什么作用?应用程序通常不会直接与物理内存交互,它们只与虚拟内存交互。这在这里有解释:(https://msdn.microsoft.com/en-us/library/windows/desktop/aa366796(v=vs.85).aspx)。 - David Schwartz
@ChrisInEdmonton 其他答案误解了问题并谈论了虚拟内存,而问题并不是关于虚拟内存的。问题非常明确地涉及对物理内存的访问,而你所需要的只是PAE,只有内核需要它。事实上,这正是PAE所做的。 - David Schwartz
这与维基百科的介绍相矛盾 https://en.wikipedia.org/wiki/Physical_Address_Extension#Design,该介绍指出“常规应用软件继续使用32位地址的指令”和“限制为4GB”。 - ChrisInEdmonton
@ChrisInEdmonton 你真的读了你引用的那一节吗?“.. 限制为4GB的虚拟地址空间”。这个问题是关于物理内存的。“.. 利用4GB以上的物理内存…”通过PAE,32位进程可以使用4GB以下或以上的物理内存而没有任何问题。物理内存的物理地址是什么并不重要,因为只有内核关心物理地址。这个问题不是关于虚拟内存或进程虚拟地址空间的。它是关于4GB以上的物理内存和物理地址的。它们完全没有关联。 - David Schwartz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接