【问题标题】:How to use more than 3 GB in a process on 32-bit PAE-enabled Linux app?如何在启用 32 位 PAE 的 Linux 应用程序上的进程中使用超过 3 GB?
【发布时间】:2010-12-15 02:52:27
【问题描述】:

PAE (Physical Address Extension) 早在 1994 年就被引入 CPU。这允许 32 位处理器访问 64 GB 的内存,而不是 4 GB。 Linux 内核从 2.3.23 开始对此提供支持。假设我正在引导其中一个内核,并且想用 C 语言编写一个可以访问超过 3 GB 内存的应用程序(为什么是 3 GB?See this)。

如何访问超过 3 GB 的内存?当然,我可以分叉多个进程;每个人都可以访问 3 GB,并且可以相互通信。但这对于大多数用例来说不是一个现实的解决方案。还有哪些其他选择?

显然,在大多数情况下,最好的解决方案是简单地以 64 位模式启动,但我的问题是关于如何在启用 PAE 的 32 位上运行的应用程序中使用 4 GB 以上的物理内存内核。

【问题讨论】:

  • “我如何编写一个可以访问超过 3GB RAM 的 C 应用程序”?那属于这里!

标签: c linux memory 32-bit


【解决方案1】:

在 Unix 上,如果/当您想要访问当前未使用的内存子集时,可以使用 mmap/munmap 访问用户空间中超过 32 位的可寻址内存。有点像手动分页。另一种方法(更简单)是通过在多个进程中使用内存的不同子集来隐式利用内存(如果您的代码具有多进程架构)。

mmap 方法本质上与 commodore 128 程序员用于银行切换的技巧相同。在这些 64 位准将时代之后,由于 64 位支持如此容易获得,没有太多充分的理由去考虑它;)

几年前,我从我们的产品中删除了所有可怕的 PAE 代码,这让我很开心。

【讨论】:

  • 感谢您注意到 Commodore 64 天和 128 天的情况。仅这一点对我来说就值得+1。 :)
【解决方案2】:

显然,在大多数情况下,最好的解决方案是简单地以 64 位模式启动,但我的问题是关于如何在启用 PAE 的 32 位上运行的应用程序中使用 4 GB 以上的物理内存内核。

您无需做任何特别的事情。只有内核需要寻址物理内存,而使用 PAE,它知道如何寻址 4 GB 以上的物理内存。该应用程序将自动使用 4 GB 以上的内存,没有任何问题。

【讨论】:

  • 这与给出的所有其他答案以及我在不同问题中阅读的几个相关答案相矛盾。你愿意引用你的答案吗?你很可能是正确的。
  • @ChrisInEdmonton 如果不允许内核访问 4GB 以上的物理内存,您认为 PAE 会做什么?应用程序不(至少,通常不)直接与物理内存交互,它们只与虚拟内存交互。这是解释here
  • @ChrisInEdmonton 其他答案误解了问题并谈到了虚拟内存,而问题与此无关。这个问题非常具体地是关于物理内存的访问,而你所需要的只是 PAE,而且只有内核需要它。事实上,这正是 PAE 所做的。
  • 这与 Wikipedia 的文章 en.wikipedia.org/wiki/Physical_Address_Extension#Design 相矛盾,其中指出“常规应用软件继续使用 32 位地址的指令”和“限制为 4 GB”。
  • @ChrisInEdmonton 您是否真的阅读了您引用的部分? “.. 限制为 4 GB 的虚拟地址空间”。这个问题是关于物理内存。 “.. 使用 4 GB 以上的 物理内存 ...” 使用 PAE,32 位进程可以毫无问题地使用 4GB 以下或以上的物理内存。内存的物理地址是什么没有区别,因为只有内核关心物理地址。这个问题与虚拟内存或进程虚拟地址空间无关。这是关于4GB以上的物理内存和物理地址。它们完全不相关。
【解决方案3】:

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

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

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

【讨论】:

  • +1 因为这是解决问题的新方法!非常好!
【解决方案4】:

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

【讨论】:

  • 是的,但是在 Windows 和 Linux 上都有访问额外内存的方法。当然,篮球可能不值得付出努力。
【解决方案5】:

您不会直接 ​​- 只要您在 32 位上运行,每个进程都将受到构建内核的 VM 拆分(2GB、3GB,或者如果您有修补过的内核) 4GB/4GB 拆分,4GB)。

让进程处理更多数据并仍将其保存在 RAM 中的最简单方法之一是创建一个 shmfs,然后将数据放入该 fs 上的文件中,使用普通的 seek/read/write 访问它们原语,或者使用mmap 一次将它们映射到内存中(这基本上相当于自己进行分页)。但无论你做什么,都比使用前 3GB 需要更多的工作。

【讨论】:

  • 您回答了不同的问题。 “[M]y 的问题严格来说是关于如何在启用 PAE 的 32 位内核上运行的应用程序中使用 4 GB 以上的物理内存。”您的答案是关于虚拟内存拆分和虚拟内存限制,而问题是关于物理内存。
【解决方案6】:

你不能有指向> 4G地址空间的指针,所以你必须做很多技巧。

应该可以通过使用mmap映射大文件的位来在不同物理页面之间切换一块地址空间;您可以随时更改映射,方法是再次调用 mmap 以更改文件中的偏移量(以 OS 页面大小的倍数计算)。

但是,这是一种非常讨厌的技术,应该避免。你打算用内存做什么?肯定有更简单的方法吗?

【讨论】:

  • 是的,更简单的方法是简单地引导 64 位内核。我预计任何解决方案都会涉及令人讨厌的黑客,我只是对它有多讨厌感兴趣。
  • 这真的取决于你的用例。如果您将 ram 用作美化的磁盘缓存,那么您可以根据需要对块进行 mmap,但它会产生很多开销,其中 mmap 需要处理页表等,即使所需的页面已经映射到 ram 中。如果您使用线程,这种方法也会失败,因为它们具有共享地址空间,因此如果没有过多的锁定,mmap 基本上是不安全的,这可能会使其效率极低。
猜你喜欢
  • 2010-10-02
  • 2011-03-19
  • 2012-01-19
  • 1970-01-01
  • 1970-01-01
  • 2011-11-02
  • 2011-12-26
  • 1970-01-01
  • 2012-02-02
相关资源
最近更新 更多