5 June 2013

Slowly into the Path of Exile

Posted by Matt
[ Since this post is targeted towards non-programmers it will be kept simple and concepts explained briefly where necessary. Follow up posts will delve into the technical aspects of some of the topics I discuss here ]

Being of the Diablo II persuasion, Path of Exile a game promoted as a homage to the original Diablo series was something I felt compelled to experience. However, shortly after slapping a few goatman-esque monsters around, my attention was drawn to the frequent in-game chatter of the seemingly popular topic of the game's technical issues and, being a programmer first (gamer second), this was beginning to sound like something interesting to investigate.

After a brief scan of the support forum, several of the frequently reportedly issues stood out:

"Unable to load resource.x: E_OUTOFMEMORY"

This was interpreted by frustrated players as being reflective of their system's lack of physical memory, which although possible, I considered to be unlikely given the ridiculous amount of memory gamers seem to have installed these days. So what could it mean then? My initial hypothesis, which has explained similar issues in the past, was that the application had reached the working set threshold which sets an upper (and lower) bound on the amount of physical memory a process can consume. This was supported by the fact it's a game, and a simple optimization technique often used in games is to request that the operating system keep as much of the program in physical memory as possible to avoid having to read from the harddrive when some portion of the program's memory is accessed.

Since I was not personally experiencing this issue I could not immediately test my hypothesis, so the next step was to find evidence for it by disassembling the game and determining whether or not the developers were locking portions of the game into memory, and if so were they ensuring the working set was keeping up. The result: Neither, they weren't locking memory or modifying the working set in any way which ruled out the working-set theory completely. Thus what remained was an application that barley consumed 1.5GB of memory that was being denied requests for more from systems which had up to 16GB (based on user reports)

This set back was short-lived however as key information came in with an error I suspected was related...

"Unable to MapViewOfFile"

Path of Exile uses a single last I checked, 12GB file to store the game assets (models, textures, etc) which is internally structured as a file-system (hence it's a vfs). A method developers often use to interact with such large files is called file-mapping as PoE does; this enables the game to treat portions of the file as if it existed in memory which often simplifies development by providing a unified model to access information, and can [in some limited cases] provide an performance increase.

Although there are numerous possibilities for this error alone (alignment comes to mind), when considered in the context of the existence of the other error (E_OUTOFMEMORY) it suggested that, along with the reports which were specifying 32-bit builds of Windows, that rather than insufficient memory it was insufficient contiguous address space. Consider address space to be a finite sequence of numbers an application uses to identify discrete segments of memory; the process of associating these numbers with segments of memory is called allocation, this is required because applications only establish this association on demand.

Unfortunately there's a problem with the address-space theory, although PoE exclusively targets an x86 (32-bit) environment which [under Windows] provides it with 2GB of address-space, the game is observed to only utilize around 1.5GB of memory. However, this can be explained by the phenomenon of fragmentation where-in, although in total, there is a sufficient quantity of address-space, there is no sufficiently sized contiguous area of the address-space that is capable of being allocated.

If true, this would make for quite an interesting turn of events; in my 15 years of programming I've never come across such a situation. Confident I found the answer, I powered up VMMap to analyze the address-space allocation pattern; sure enough, PoE's data was sprayed all over the place. Except, there's one problem: why wasn't I experiencing the same issue? The answer lies in the fact my machine is 64-bit, and although PoE is an 32-bit executable, it was decided by the Windows developers to free up the high-half of the 32-bit address space for WoW64 processes and allow 32-bit processes to utilize the entire 32-bit address-space if the image is marked as such (ie., /LARGEADDRESSAWARE). Finally there's an explaination, but what about a solution? Luckily Windows has a boot flag that enables processes (on 32-bit systems) to access up to 3GB of memory by shifting the user/kernel address-space allocation around a bit. This doesn't solve the problem, but it will delay it's onset.

There is one remaining question, if the PoE developers were aware (evidenced the image being marked with the aforementioned flag) that the game could potentially require more address-space than is available on 32-bit Windows, then why would they not mention it to the players?


Originally I was going to cover a performance issue aswell (which is what the title is referring to) however I think this post has gone on long enough.

29 May 2014 7:29pm
Leonaldo Brum wrote:

This looks like good reasoning to me.A "unified" method or convention needs to exist for Operating Systems to safely handling requests for memory allocation. This method would, first of all, guarantee that a few rule would be enforced and all requesting applications would be able to incorporate the handling of the OS response in their patterns and feedback to users.Typically the 2 major feedback messages from the OS would be:- Request granted, X amount of memory allocated.- Impossible to allocate requested memory now.In some cases, like the ones you mention, an extension of the allocated memory could be requested - and equivalent responses provided.Now, a model for "acceptable" waiting times could be programmed into the application, which, if implemented, could allow for a new request to be sent momentarily. But this is not very compatible with a communications environment, so dependent upon other parties' timings.The dynamic allocation of memory could also work, but only between boundaries (min- max) in order to insure that minimum operating memory would be available at all times.Finally, it would be the application's responsibility to insure that a continuous space would always be available. This is where I don't know whether OS's can comply. A "falsely contiguous" memory space would have to be apparent to the application as truly contiguous, so that orders from the application that required moving blocks would in fact be moving stuff located in disparate locations in the host machine. The EMS memory model of yesterdays comes to my mind as a viable model for this... I think it is no longer used, but had this addressing capability included, which would help resolve the OS attributing fragmented memory space and the application "believing" it was contiguous. Many a spreadsheet I ran using this transparent model, but at the time we were not multi-user or multi-tasking...Besides, modern OS may need to relocate the whole or portions of the application memory - without the application even knowing about it.
22 October 2014 4:36pm
cbjlwdbfll wrote:

b1DrAR ifcxrqtsskgm, [url=]gztzdzhmiyli[/url], [link=]gqzmpnyjkoam[/link],

Add Comment



What is 1+1?