A Messy Transition: Practical Problems With 32bit Addressing In Windows
by Ryan Smith on July 12, 2007 12:00 PM EST- Posted in
- Software
In 1986, Intel released the 386 processor, which offered support for a new instruction set (IA32), that was an extension of the original x86 instruction set. Among the most notable features in IA32 was an increase in the amount of memory the CPU could address, moving from 20bit addressing(1MB) to 32bit addressing(4GB)(ed: this is not including the convoluted mess that was segmented addressing). All x86 CPUs released since then have supported the same instruction set, including the same 4GB limit. Only recently have 64bit x86 CPUs been released, and while they support more than 4GB of memory, still are limited to 4GB when operating in 32bit mode.
As we have mentioned in previous articles, most modern system running in 32bit x86 mode have trouble seeing and using more than roughly 3GB of memory. This is because part of the total 4GB of memory space (not the physical memory) is reserved for various functions, such as computer components transferring data between each other using memory-mapped input-output(MMIO). The textbook example of this is the CPU transferring data to the memory of a video card, where a chunk of the address space equal to the size of the memory of the video card is reserved by the video card, and any data sent to those addresses actually ends up going to the video card. This design has many technical merits, but it makes the consumed memory addresses unavailable for use with physical memory.
Things only get more complex as we start including the operating system (in this case Windows) in to the equation. The above is actually handled by a combination of Windows and the BIOS, meanwhile Windows also needs some address space so that programs can communicate with the Windows kernel, for storing buffers, for storing memory tables, etc; all of which means we have lost even more address space. All of the above besides preventing us from addressing 4GB of physical memory are also the cause of the actual 2GB barrier that is the problem.
Quickly, there is one more pre-requisite piece of information: virtual address space. For a 32bit Windows application(Win32), each application has a full 4GB worth of private addressing space that it can use, which again is 32bits and a result of how a 32bit processor works. How the above exactly works is beyond the scope of this article, but it's sufficient to say that at some point virtual addresses get translated in to other addresses for mapping data between the application and physical memory or the swap file. The important thing to take from this is that each application has its own 4GB virtual address space, regardless of the hardware the computer contains or what applications are running. Now we may begin to understand the 2GB barrier.
Due to design reasons outside the scope of this article, Windows takes a pre-determined portion of each application's virtual address space and reserves it for itself. Windows uses its portion of the virtual address range for all of the address needs listed above. At the end of the day, and what really matters, is that in designing Windows Microsoft opted to split up the virtual address space of an application in half; 2GB goes to Windows (kernel space) and 2GB goes to the application (user space). Under normal circumstances this 2GB of space is all a 32bit application has to work with, this is the 2GB barrier and as we'll see is the cause of the problems with Supreme Commander.
It is also worth noting at this point that virtual address space is not directly correlated to physical memory size. Windows and any applications running under it may use up to all of their allocated virtual address space, with Windows simply swapping data between the hard drive and physical memory if the amount of physical memory needed is in excess of what's available - this is virtual memory, not to be confused with virtual address space. The only meaningful relation between virtual address space and physical memory is that the amount of physical memory an application can use can never be greater than its virtual address space. The user space must take up a larger portion of the virtual address space if an application is to use more than 2GB of physical memory.
69 Comments
View All Comments
miahallen - Saturday, July 14, 2007 - link
What I found extremely interesting is that you had problems modifying your boot.ini file for a lsrger than 2.6GB app space. I have an almost identical configuration, and have modded almost all my games headers, and my boot.ini is set to 3GB app space. When I modded the boot.ini, I was unaware of the possible problems, but since it didn't cause any, I've been perfectly happy with it.A8N-SLI Delux
Opty 165 @ 2.5GHz
2GB DDR400
8800GTX (768MB VRAM)
Vista x86
I've modded the headers for:
STALKER
C&C3
CoH
Dark Messiah M&M
DiRT
FSX
Silent Hunter 4
TDU
Thanks Ryan, for the great article!
MadBoris - Sunday, July 15, 2007 - link
This should be made clear to people.
If an application is not Large Address Aware there is usually very good reason the developers did not include it that way. There maybe things you break in the game or cause stability problems by adding it.
So people should not be just adding this to all their games, especially considering many games don't come close to the 2GB ceiling in the first place, so their is no benefit only potential negatives.
ChristopherO - Monday, July 16, 2007 - link
This is true... One shouldn't go setting the binary flag because they *can*.I will however confirm that C&C3 and FSX run into the 2GB barrier. FSX is fine once it is patched.
However, C&C3 is so poorly written that it can easily pass 2GB and run into the revised 3GB barrier on any multiplayer map with the maximum number of AI and/or opponents. Detail settings as low as the "medium" preset do nothing to alleviate this problem.
Unfortunately C&C apparently has absolutely no code to purge and re-use memory as I've been in huge games, on the downward slope in terms of remaning opponents/units, and the app still hits a revised 3GB memory space and crashes.
As a developer myself, memory management is *not* that complicated. It takes some forethought, but the EA people apparently never bothered. This is a huge letdown since I've been a C&C fan since the first game came out my first year of college.
miahallen - Saturday, July 14, 2007 - link
I have to add one more thing about my system, may be important.....most of my games I play at 2048x1536, as opposed to you test rig at 1600x1200. That and you were using Vista Ultimate, I'm using Home Premium. Do you think this is what is effecting the results? If so, Home Premium (or even Home Basic) is the x86 OS of choice for gamers, not Ultimate!miahallen - Sunday, July 15, 2007 - link
I was hoping you would comment on this Ryan, do you think the difference in our boot.ini mod was due to the version of Vista we run? Any thoughts?sheh - Thursday, July 12, 2007 - link
...and disturbingly it doesn't set off any sort of multiplayer cheat detection in the game in spite of the fact that we have modified the executable in a very visible way.The game probably checks the code (and maybe data) section(s) in memory, and not the actual EXE file (makes sense considering you can use memory patchers). The header might not be important for cheat prevention.
MadBoris - Thursday, July 12, 2007 - link
Yeah, I remember thinking that the first day I did it, actually in those days it was Securom protected which I was actually more suprised about bypassing. But seriously the exe header should not be something that cheat protection should look for. I can only say glad it didn't or crashing would be a constant problem. ;)
atlr - Thursday, July 12, 2007 - link
I thoroughly enjoyed this article. Good job.atlr - Thursday, July 12, 2007 - link
A lot of good comments have helped edit and tune this article too. (meh, not this one though) Yayyy, community.JetBlack69 - Thursday, July 12, 2007 - link
From a programming perspective, what is a programmer to do? I assume this can happen in a program when "new" returns NULL because the program is out of memory, but what can a program do gracefully?I assume it could just display an error message, but if it were during a game, how could it handle it gracefully and not crash or give an error message? Would it lower the texture detail or remove unneeded objects on the screen?