• Advertisement

Archived

This topic is now archived and is closed to further replies.

Using lotsa' memory under Windows

This topic is 6556 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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

Share this post


Link to post
Share on other sites
Advertisement
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
>>>> 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

Share this post


Link to post
Share on other sites
I think you should use RLE images here. You''ll loose some performance, but with a strong asm routine you''ll get your hands free with the subject.

If you need just 12MB for the background, and lets say 2MB for the sprites (and their framesets), then what will be left to load sounds????

Think about it.

Another way might be to load parts of the image each time. If the user uses 800x600, you might load a screen of 1600x1600, though i''d prefer the RLE solution.

c ''ya

Share this post


Link to post
Share on other sites
According to bstach, if I were to use *any* Windows functions for my memory allocation, there''s the risk of disk-swapping. So, I will probably just use my archaic dos extender code, which is ''XLIB'' by TechniLib. (like Qoy pointed out, the old dos version of my game *does* work under Windows).

Now, some of you are saying that I should just use Windows mempory alloc funtions and let it do its disk-swap thing, but I personally think this would take way too much time, even if it were only a couple megs every cycle.

Lotan and Harvester: yes, my game will probably require a machine w/ more than 16 MB. Perhaps I will start a thread about how much RAM a game should require these days. Harvester: you suggested RLE (run-length encoding). For anyone unfamiliar with this, its a way to compress images when you have long runs of a single color. Harvester, if you looked at my screenshot in one of the previous posts, I can see why you''d suggest this. However, in my current version, I plan to eliminate any flat spots in the terrain, because they look unnatural, so there won''t be any single-color ''runs''.

Share this post


Link to post
Share on other sites
Ok, there have been a few SERIOUSLY wrong posts here. At least in their assumptions.

First, BSTATCH was 100% correct in his assertion that if the user does not have enough memory, than windows will move around the memory it can (must) in order to execute the program. THERE IS NO WAY AROUND THIS. By definition, a system with insufficient memory MUST use virtual memory, or stop executing (aka CRASH).

Second, you CANNOT assume you are the only program running, EVEN in full screen exclusive mode. That only ensures that you are the only DirectDraw program running. What are you going to do when the users running FTP, a Virus Scanner, or a security logging routine in the background. If you lock 70-80% of the memory, than you are going to bring the system to its knees, and this INCLUDES your program, because windows will give your program exactly the same time slice as the other programs (maybe even less if they are high priority). Even if you are the only program running, trying to detect ALT-TAB in order to deallocate memory is basically the EXACT SAME thing windows would do anyway, which is leave eveything in use in memory, and remove old data when new data needs space.

Third, you WILL NOT manually manage memory better than Windows does. Windows (and Linux, and BeOS, etc etc) manage memory using a VERY effiecient algorithm with the goal of MINIMIZING disk accesses. You can only HURT the built in memory management system by denying it the ability to move your blocks of memory. WINDOWS WILL NOT put your 12MB file on the disk unles it runs out of space. AND EVEN THEN it only move PARTS of your programs data to disk, THE LEAST USED PARTS, so that will NEVER be your 12MB block if it is used every couple of frames.

Fourth, Windows would not even have to move your whole 12MB file to disk, just because you THINK of it as a logical block. Windows sees the world in equally valuable pages, each of which are independent. So if your program is running on a computer which has 1MB too little memory, it will only swap 1MB memory to disk, and any or none of that 1MB might be your 12MB structure. Also, it will not affect you AT ALL, since windows will automatically page in memory you try to access, by LOOKING AHEAD at upcoming instructions, just like L1 and L2 memory cache, which is USUALLY BETTER than the code you would write to manage the memory.

Since Windows is running it's own thing in the background, including device drivers and scheduled applications, you can ONLY hurt your user by force locking memory. And if he doesn't have enough memory, say he has 16MB, you would be forcing his hard drive to crash MUCH earlier than normal, by thrashing everything in and out of the remaining 4MB of memory. I don't even want to imaging if you had a memory leak with little 100K blocks of unmoveable memory. Soon the users hard drive is trashing away, AND his computer is locked, a surefire way to generate bad sectors on the hard disk when the user forces a cold reboot.

NOTE: YOUR DOS EXTENDER DOES NOT GIVE YOU NON-VIRTUAL MEMORY. Windows runs each does app in a virtual space just like a windows app. Hence the reason most programs are compatible, but many low level utilities are not (they relied on EXACT non-virtual addresses). Windows will simply LIE to your program, to you it will seem unchanging, just as if you used the built in C++ memory allocation (much easier but in reality it will move anywhere windows wants.

Edited by - Xai on 3/9/00 10:43:25 PM

Share this post


Link to post
Share on other sites
Why move your game to Windows if you won't let other apps run at the same time? Doesn't that kind of defeat the purpose?

Also, why allocate the memory yourself? Why not create a DirectDraw surface?

Good Luck!


- null_pointer


Edited by - null_pointer on 3/10/00 7:40:54 AM

Share this post


Link to post
Share on other sites
Eric: Didn''t mean to be rude -- just wanted to point out that programming under Windows means sharing resources and using other people''s libs. It''s a whole different mindset from DOS. It''s one thing to make a great game that hogs the whole computer -- it''s quite another thing to make a great game that lets you browse on the internet for tips or chat at the same time! The possibilities are endless...

Good Luck!


- null_pointer

Share this post


Link to post
Share on other sites

  • Advertisement