Memory limits on 32-bit and 64-bit machines

From Helpful
Jump to navigation Jump to search

The lower-level parts of computers

General: Computer power consumption · Computer noises

Memory: Some understanding of memory hardware · CPU cache · Flash memory · Virtual memory · Memory mapped IO and files · RAM disk · Memory limits on 32-bit and 64-bit machines

Related: Network wiring notes - Power over Ethernet · 19" rack sizes

Unsorted: GPU, GPGPU, OpenCL, CUDA notes · Computer booting




This article/section is a stub — some half-sorted notes, not necessarily checked, not necessarily correct. Feel free to ignore, or tell me about it.


tl;dr:

  • If you want to use significantly more than 4GB of RAM, you want a 64-bit rather than 32-bit OS.
  • ...and since that is now typical, most of the details below are irrelevant


TODO: the distinction between (effects from) physical and virtual memory addressing should be made clearer.


Overall factoids

OS-level and hardware-level details:

From the I want my processes to map as much as possible angle:

  • the amount of memory a single process could hope to map is typically limited by its pointer size,
    • so ~4GB on 32-bit OS,
    • lots on a 64-bit OS.
How much actually varies, because it's not only about the OS, it's also about what hardware chooses to do natively, because anything else would be slow, so it's still terabytes, not exabytes.
  • On 32-bit it was relevant that most OS kernels have a split (for their own ease) that, long story shourt, means that even if a process could point at 4GB, it may only allocate 3GB, 2GB sometimes even 1GB
(this is partly a pragmatic implementation detail from back when 32 megabytes was a lot of memory, and leftover ever since)


  • Since the OS is in charge of virtual memory, it can map each process to memory separately, so in theory you can host multiple 32-bit processes that together use much more than 4GB
...even on otherwise 32-bit OSes: you can for example compile the 32-bit linux kernel to use up to 64GB this way
a 32-bit OS can only do this through PAE, which has to be supported and enabled in motherboard, and supported and enabled in the OS.
Note: both 32-bit and 64-bit PAE-supporting motherboards may have somewhat strange limitations, e.g. the amount of memory they will actually allow/support (mostly a problem in early PAE motherboards)
and PAE was problematic anyway - it's a nasty hack in nature, and e.g. drivers had to support it. It was eventually disabled in consumer windows (XP) for this reason. In the end it was mostly seen in servers, where the details were easier to oversee.


  • device memory maps would take mappable memory away from within each process, which for 32-bit OSes would often mean that you couldn't use all of that installed 4GB



On 32-bit systems:

Process-level details:

  • No single 32-bit process can ever map more than 4GB as addresses are 32-bit byte-addressing things.
  • A process's address space has reserved parts, to map things like shared libraries, which means a single app can actually allocate less (often by at most a few hundred MBs) than what it can map(verify). Usually no more than ~3GB can be allocated, sometimes less.


On 64-bit systems:

  • none of the potentially annoying limitations that 32-bit systems have apply
(assuming you are using a 64-bit OS, and not a 32-bit OS on a 64-bit system).
  • The architecture lets you map 64-bit addresses
...in theory, anyway. The instruction set is set up for 64 bit everything, but the current x86-64 CPU implementation's address lines are 48-bit (for 256TiB), mainly because we can increase that later without breaking compatibility, and right now it saves copper and silicon 99% of computers won't use
...because in practice it's still more than you can currently physically put in most systems. (there are a few supercomputers for which this matters, but arguably even there it's not so important because horizontal scaling is generally more useful than vertical scaling. But there are also a few architectures designed with a larger-than-64-bit addressing space)


On both 32-bit (PAE) and 64-bit systems:

  • Your motherboard may have assumptions/limitations that impose some lower limits than the theoretical one.
  • Some OSes may artificially impose limits (particularly the more basic versions of Vista seem to do this(verify))


Windows-specific limitations:

  • 32-bit Windows XP (since SP2) gives you no PAE memory benefits. You may still be using the PAE version of the kernel if you have DEP enabled (no-execute page protection) since that requires PAE to work(verify), but PAE's memory upsides are disabled (to avoid problems with certain buggy PAE-unaware drivers, possibly for other reasons)
  • 64-bit Windows XP: ?
  • /3GB switch moves the user/kernel split, but a single process to map more than 2GB must be 3GB aware
  • Vista: different versions have memory limits that seem to be purely artificial (8GB, 16GB, 32GB, etc.) (almost certainly out of market segregation)

Longer story / more background information

A 32-bit machine implies memory addresses are 32-bit, as is the memory address bus to go along. It's more complex, but the net effect is still that you can ask for 2^32 bytes of memory at byte resolution, so technically allows you to access up to 4GB.


The 'but' you hear coming is that 4GB of address space doesn't mean 4GB of memory use.


The device hole (32-bit setup)

One of the reasons the limit actually lies lower is devices. The top of the 4GB memory space (usually directly under the 4GB position) is used to map devices.

If you have close to 4GB of memory, this means part of your memory is still not addressible by the CPU, and effectively missing. The size of this hole depends on the actual devices, chipset, BIOS configuration, and more(verify).


The BIOS settles the memory address map(verify), and you can inspect the effective map (Device Manager in windows, /proc/iomem in linux) in case you want to know whether it's hardware actively using the space (The hungriest devices tend to be video cards - at the time having two 768MB nVidia 8800s in SLI was one of the worst cases) or whether your motherboard just doesn't support more than, say, 3GB at all. Both these things can be the reason some people report seeing as little as 2.5GB out of 4GB you plugged in.


This problem goes away once you run a 64-bit OS on a 64-bit processor -- though there were some earlier motherboards that still had old-style addressing leftovers and hence some issues.


Note that the subset of these issues caused purely by limited address space on 32-bit systems could also be alleviated, using PAE:

PAE

It is very typical to use virtual memory systems. While the prime upside is probably the isolation of memory, the fact that a memory map is kept for each process also means that on 32-bit, each application has its own 4GB memory map without interfering with anything else (virtual mapping practice allowing).

Which means that while each process could use 4GB at the very best, if the OS could see more memory, it might map distinct 4GBs to each process so that collectively you can use more than 4GB (or just your full 4GB even with device holes).


Physical Address Extension is a memory mapping extension (not a hack, as some people think) that does roughly that. PAE needs specific OS support, but doesn't need to break the 32-bit model as applications see it.

It allowed mapping 32-bit virtual memory into the 36 bit hardware address space, which allows for 64GB (though most motherboards had a lower limit)


PAE implies some extra work on each memory operation, but because there's hardware support it only kicked a few percent off memory access speed.


All newish linux and windows version support PAE, at least technically. However:

  • The CPU isn't the only thing that accesses memory. Although many descriptions I've read seem kludgey, I easily believe that any device driver that does DMA and is not aware of PAE may break things -- such drivers are broken in that they are not PAE-aware - they do not know the 64-bit pointers that are used internally used should be limited to 36-bit use.
  • PAE was disabled in WinXP's SP2 to increase stability related to such issues, while server windowses are less likely to have problems since they use tend to use more standard hardware and thereby drivers.

Kernel/user split

This article/section is a stub — some half-sorted notes, not necessarily checked, not necessarily correct. Feel free to ignore, or tell me about it.

The kernel/user split, specific to 32-bit OSes, refers to an OS-enforced formalism splitting the mappable process space between kernel and each process.


It looks like windows by default gives 2GB to both, while (modern) linuces apparently split into 1GB kernel, 3GB application by default (which is apparently rather tight on AGP and a few other things).

(Note: '3GB for apps' means that any single process is limited to map 3GB. Multiple processes may sum up to whatever space you have free.)


In practice you may want to shift the split, particularly in Windows since almost everything that would want >2GB memory runs in user space - mostly databases. The exception is Terminal Services (Remote Desktop), that seems to be kernel space.

It seems that:

  • linuxes tend to allow 1/3, 2/2 and 3/1,
  • BSDs allow the split to be set to whatever you want(verify).
  • It seems(verify) windows can only shift its default 2/2 to the split to 1GB kernel, 3GB application, using the /3GB boot option (the feature is somewhat confusingly called 4GT), but it seems that windows applications are normally compiled with the 2/2 assumption and will not be helped unless coded to. Exceptions seem to primarily include database servers.
  • You may be able to work around it with a 4G/4G split patch, combined with PAE - with some overhead.

See also