PAE(物理地址扩展)早在 1994 年就在 CPU 中引入。这允许 32 位处理器访问 64 GB 内存而不是 4 GB。 Linux 内核从 2.3.23 开始提供对此的支持。假设我正在启动这些内核之一,并且想要用 C 编写一个应用程序,该应用程序将访问超过 3 GB 的内存(为什么是 3 GB?请参阅此)。
我该如何访问超过 3 GB 的内存?当然,我可以分叉多个进程;每个人都可以访问 3 GB,并且可以相互通信。但这对于大多数用例来说并不是一个现实的解决方案。还有哪些其他选择?
显然,大多数情况下最好的解决方案是简单地以 64 位模式启动,但我的问题严格来说是如何在启用 PAE 的 32 位内核上运行的应用程序中使用 4 GB 以上的物理内存。
PAE (Physical Address Extension) was introduced in CPUs back in 1994. This allows a 32-bit processor to access 64 GB of memory instead of 4 GB. Linux kernels offer support for this starting with 2.3.23. Assume I am booting one of these kernels, and want to write an application in C that will access more than 3 GB of memory (why 3 GB? See this).
How would I go about accessing more than 3 GB of memory? Certainly, I could fork off multiple processes; each one would get access to 3 GB, and could communicate with each other. But that's not a realistic solution for most use cases. What other options are available?
Obviously, the best solution in most cases would be to simply boot in 64-bit mode, but my question is strictly about how to make use of physical memory above 4 GB in an application running on a PAE-enabled 32-bit kernel.
发布评论
评论(6)
在 Unix 上,如果/当您想要访问当前未使用的内存子集时,访问用户空间中超过 32 位可寻址内存的一种方法是使用 mmap/munmap。有点像手动分页。另一种方法(更简单)是通过在多个进程中使用内存的不同子集来隐式利用内存(如果您的代码具有多进程架构)。
mmap 方法本质上与 Commodore 128 程序员用于存储库切换的技巧相同。在 Commodore-64 后的日子里,64 位支持如此容易获得,没有太多充分的理由去考虑它;)
几年前,我很高兴从我们的产品中删除所有可怕的 PAE 代码。
On Unix one way to access that more-than 32bit addressable memory in user space by using mmap/munmap if/when you want to access a subset of the memory that you aren't currently using. Kind of like manually paging. Another way (easier) is to implicitly utilize the memory by using different subsets of the memory in multiple processes (if you have a multi-process archeteticture for your code).
The mmap method is essentially the same trick as commodore 128 programmers used to do for bank switching. In these post commodore-64 days, with 64-bit support so readily available, there aren't many good reasons to even think about it;)
I had fun deleting all the hideous PAE code from our product a number of years ago.
不能让指针指向 > 4G的地址空间,所以你必须做很多技巧。
通过使用 mmap 映射大文件的位,应该可以在不同物理页之间切换地址空间块;您可以随时通过再次调用 mmap 来更改映射,以更改文件中的偏移量(以操作系统页面大小的倍数表示)。
然而,这是一种非常令人讨厌的技术,应该避免。你打算用内存做什么?当然有更简单的方法吗?
You can't have pointers pointing to > 4G of address space, so you'd have to do a lot of tricks.
It should be possible to switch a block of address space between different physical pages by using mmap to map bits of a large file; you can change the mapping at any time by another call to mmap to change the offset into the file (in multiples of the OS page size).
However this is a really nasty technique and should be avoided. What are you planning on using the memory for? Surely there is an easier way?
您无需做任何特别的事情。只有内核需要对物理内存进行寻址,并且通过 PAE,它知道如何对 4 GB 以上的物理内存进行寻址。该应用程序将自动使用 4 GB 以上的内存,不会出现任何问题。
There's nothing special you need to do. Only the kernel needs to address physical memory, and with PAE, it knows how to address physical memory above 4 GB. The application will use memory above 4 GB automatically and with no issues.
你不需要,直接 - 只要你在 32 位上运行,每个进程都将受到构建内核所用的 VM 分割(2GB、3GB,或者如果你有一个带有 4GB 的修补内核) /4GB 分割,4GB)。
让进程处理更多数据并仍将其保留在 RAM 中的最简单方法之一是创建一个 shmfs,然后将数据放入该 fs 上的文件中,通过普通的查找/读取来访问它们/write 基元,或者使用
mmap
将它们一次映射到内存中(这基本上相当于您自己进行分页)。但无论你做什么,都比使用第一个 3GB 需要更多的工作。You don't, directly -- as long as you're running on 32-bit, each process will be subject to the VM split that the kernel was built with (2GB, 3GB, or if you have a patched kernel with the 4GB/4GB split, 4GB).
One of the simplest ways to have a process work with more data and still keep it in RAM is to create a
shmfs
and then put your data in files on that fs, accessing them with the ordinary seek/read/write primitives, or mapping them into memory one at a time withmmap
(which is basically equivalent to doing your own paging). But whatever you do it's going to take more work than using the first 3GB.或者,您可以根据需要启动任意数量的 memcached 实例,直到映射所有物理内存。每个 memcached 实例可以在 32 位计算机上提供 3GiB 可用空间。
然后通过 memcached 的API 和语言绑定分块访问内存。根据应用程序的不同,它可能几乎与直接在 64 位平台上运行一样快。对于某些应用程序,您可以获得创建可扩展程序的额外好处。没有多少主板可以处理超过 64GiB RAM,但使用 memcached,您可以轻松访问您可以支付的尽可能多的 RAM。
编辑请注意,这种方法当然也适用于 Windows 或任何可以运行 memcached 的平台。
Or you could fire up as many instances of memcached as needed until all physical memory is mapped. Each memcached instance could make 3GiB available on a 32 bit machine.
Then access memory in chunks via the APIs and language bindings for memcached. Depending on the application, it might be almost as fast as working on a 64-bit platform directly. For some applications you get the added benefit of creating a scalable program. Not many motherboards handle more than 64GiB RAM but with memcached you have easy access to as much RAM as you can pay for.
Edited to note, that this approach of course works in Windows too, or any platform which can run memcached.
PAE 是硬件地址总线的扩展,以及一些页表修改来处理它。它并没有改变指针仍然是 32 位的事实,从而将单个进程中的地址空间限制为 4G。老实说,在现代世界中,编写需要超过 2G(Windows)或 3G(Linux)地址空间的应用程序的正确方法是简单地针对 64 位平台。
PAE is an extension of the hardware's address bus, and some page table modifications to handle that. It doesn't change the fact that a pointer is still 32 bits, limiting you to 4G of address space in a single process. Honestly, in the modern world the proper way to write an application that needs more than 2G (windows) or 3G (linux) of address space is to simply target a 64 bit platform.