Advertisement

Using lotsa' memory under Windows

Started by March 07, 2000 03:12 AM
13 comments, last by Eric 24 years, 9 months ago
I am working on a game to be run in Windows so that I can utilize DirectX, and I need like 12 MB RAM for a particular array. The game is actually almost a port from a DOS version I did years ago; back then, I used a DOS extender to allocate such large arrays. I have very little Windows programming experience, btw. So I''m reading about Windows memory recently in their platform SDK: Apparently your process gets 2 GB to squander, which sounded great until I read that Windows might just decide to store my array on disk instead of RAM. Loading a 12-meg file every cycle will not help my frame-rate. Actually, I guess you can ''lock'' memory to guarantee that it stays in RAM, so maybe that''s not an issue. Still, my question is this: Do games running under Windows generally use this virtual memory system? Since the virtual address you''re given isn''t the actual, physical address of your stuff, it sounds very inefficient/slow. Also, if this is *not* the prescribed method of getting lotsa'' memory under Windows, what is? Thanks for your help
I use GlobalAlloc() to allocate memory. as long as you specify GMEM_FIXED you don''t have to worry about it being moved to virtual mem. I allocate all my mem with this flag and then handle disk swapping myself. This way i know exactly what occupies physical memory and what lies on the disk.
Advertisement
oops i forgot to mention that GlobalAlloc() with GMEM_FIXED does return a pointer to the actual address of the memory instead of a HGLOBAL as with moveable memory.
Honestly, I don''t think you should have to worry about it. Modern virtual memory and cache systems are designed to do the dirty work for you. Do you actually think that the entire 12 MB file is going to be refetched from disk on every access? Of course not. But Windows (and any other modern OS) can handle multiple processes at once. Therefore, you HAVE to use virtual memory, or you very quickly run out. It''s a simple fact of life. My advice: don''t worry about it. If your process is active, and nothing is else is hogging RAM, then as long as you don''t go allocating tons more memory than you have physically, everything SHOULD be in RAM.

-Brian
Just out of interest, what are you using a 12Mb array for exactly?

Thats six times as much memory the playstation has available in total....

Game production:
Good, quick, cheap: Choose two.
Game production:Good, quick, cheap: Choose two.
If you have a data block that big then you definitly should worry about where it gets stored. I would reiterate what ThomasAtwood said about using the GMEM_FIXED bit. Keep in mind though that this is a good way to use up all your system''s RAM and potentially crash the OS, so I would only do it when necessary.
Mike Weldon, a.k.a. FalloutBoymweldon@san.rr.com
Advertisement
Yeah, ThomasAtwood & FalloutBoy, GlobalAlloc() sounds like what I need. I did read the following in the SDK, though:

"If you expect your memory blocks to be larger than one or two megabytes, you can avoid significant performance degradation by using the VirtualAlloc or VirtualAllocEx function instead."

This probably relates to osmanb''s point about multi-processing. However, I don''t care how many processes Windows can handle simultaneously; I might as well hog as much physical RAM as I need, because when my game is running (full-screen), what else would the user be doing anyway, right? (FalloutBoy: if they alt-tabbed out my application while it was running, then yeah, they''d be outta memory... I suppose I could deallocate whenever they do that).

Danack asked what the 12 MB is for: I have up to a 2500x2500 background image that must be in memory at all times (it''s not tile-based). That image will of course be in VRAM, but it also needs sort-of a z-buffer, 2 bytes/pixel, hence 12 MB.

Screenshot from DOS version: a hovercraft getting a little air

Thanks for everyone''s help
Just a thought, but when you run your DOS version in Windows, Windows might actually manage the virtual memory almost the same way it would if you just allocated memory normally. I don''t know though.. So if your DOS version runs fine from Windows, it might be OK.
Here''s the problem I see with making the 12MB be in memory:
Windows will do what Windows wants, and if you have 16Meg of memory and windows decides it needs 5MB for something, and you already have used 12, it might just page the 4 around constantly, and you''re no better off than paging the 12 MB in and out. I say don''t mess with Windows, if you don''t have the physical memory, your going to use virtual one way or another.
>>>> From post by ThomasAtwood

I use GlobalAlloc() to allocate memory. as long as you specify GMEM_FIXED you don't have to worry about it being moved to virtual mem. I allocate all my mem with this flag and then handle disk swapping myself. This way i know exactly what occupies physical memory and what lies on the disk.

<<<<

Just one little clarification.

GMEM_FIXED does NOT lock your memory into physical ram and keep it from being swapped to disk. It is just a flag left over from the Win16 days of segmented memory and the funky Windows 3.1 virtual memory scheme.

GlobalAlloc() and the related LocalAlloc() functions only exist for backwards compatibility with code ported from Win16. GMEM_FIXED and GMEM_MOVEABLE are equivalent under Win32. The only diference is that with GMEM_FIXED you get a pointer to the memory and you are gauranteed that the OS is not going to change the virtual memory address (but it will move it all over physical memory and swap it to disk). With GMEM_MOVEABLE you get a handle to the memory and windows may change the virtual address of the memory at will (but it is very rare that windows would) until you call GlobalLock(). In either case windows will still swap out the memory to disk when it needs to.

Stick to the the C and C++ memory routines, you are not gaining anything under Win32 by using GlobalAlloc().

The only time you can get truly non-swappable memory in Win32 is to write kernal level code designed to run at ring 0 (primarily device drivers). Even then you have to treat the memory as if it were the last piece of memory on earth or you will bring the kernal down in a glorious fireball!

Just wanted to clear up a common misconception about Win32 memory management.

Just thought I would add a few references for people not clear on this subject:

MSDN help overview on memory management.
MSDN help on the GlobalAlloc() and LocalAlloc() functions.
Programming Windows95 by Charles Petzold (The windows programmer's bible) page 728.

Edited by - bstach on 3/8/00 1:33:33 AM

Edited by - bstach on 3/8/00 1:36:12 AM

This topic is closed to new replies.

Advertisement