views:

232

answers:

5

Hi guys, My environment is XP 32-bit. I find when allocated memory is nearly the maximum size, 2GB, that means a little virtual space is available, allocationnew memory is very slow.

So if I have a page file, my app need to analyze them. I have two ways. One is to read them all into system memory, then do the analysis. The other is to reserv a memory buffer first as a cache, and read part of page file into that buffer, analyze and then discard it, then read second part of page file, and override the cache, do the analysis again.

From the profiling, it looks the second one is faster, since it avoid the allocation time cost.

What do you think? Thanks in adavance.

+6  A: 

You forget 3d way - to map memory onto file, see function CreateFileMapping/MapViewOfFile This is most fast way

Dewfy
It's the other way around. The file is mapped into the process address space.
Void
A: 

Why is the amount allocated memory so high? If memory allocations take a reasonable amount of time then you will find doing it in memory is far far quicker - my approach would be to do it in memory, and try to find a way to reduce the memory usage to the point where its quick again.

Kragen
+1  A: 

You best bet is to use the windows MapViewOfFile and similar functions (the Windows equivalent of mmap). This will allow the operating system to manage the paging in of various parts of the file.

doron
But if I have multiple large page files (1.8GB), is this OK?
Buzz
The OS will map the whole file into your process's memory but will only load the bits of the file that you are looking at into ram. This is exactly the way the OS manages its disk swap space.
doron
@Buzz: you can't map the whole of multiple 1.8GB files into the same 32 bit process at the same time, because the virtual space has to be allocated even though the physical memory is only committed as needed. Different files in different processes should be OK as far as I know, and you can always map the file in chunks (in the same way your second option reads chunks, but mapping bigger chunks).
Steve Jessop
+5  A: 

(1) I'm not sure the question matches the title. If you're allocating close to 2GB of RAM on 32 bit Windows, the system is probably paging a lot of memory to disk, and that's where I'd look first for the slow down. When you're using a lot of memory, you should think of it as being stored on disk (in pagefile.sys) but cached in physical RAM. The second one might be faster not because of the cost of doing allocation, but because of the cost of using a lot of memory at once. In effect when you copy the file into one big allocation you're copying much of it disk->disk via RAM, then when you run over it again to analyse, you're loading the copy back to RAM again. If your analysis is a single-pass algorithm that's a lot of redundant work.

(2) What I think is, mmap the file (MapViewOfFile and friends on Windows).

Edit: (3) a caution. If the file is currently 1.8GB, there might be a chance that next year it might be 4GB. If so, I'd plan now for it to have a size greater than 2^32 on a 32bit machine, which means either taking your second option, or else still using MapViewOfFile but doing it one sensible-sized chunk of the file at a time, rather than all at once. Otherwise you'll be revisiting this code the first time someone tries it on a big file and reports the bug.

Steve Jessop
Thanks. It's interesting. But I have 4GB ram. From task manager, available physical RAM is 1.6GB free. Does this still mean lots of buffer would be placed in the sys page file when allocation is close to 2GB?
Buzz
Buffer allocation could fail well before RAM runs out. The question is whether you are running a 64 bits Windows. That allows you to use >2GB _RAM per process_.
MSalters
@MSalters: The questioner is not running 64 bit Windows. @Buzz: you'd think that Windows wouldn't hit swap (for non-idle programs) before all RAM is in use, but it never seems to work that way. It's possible that in your case there's no swapping, but if I was trying to fully explain the performance difference between your two options I'd want to rule it out - as the simplest check, ensure that page file use doesn't increase while your program is running. Next after that would be to look at CPU cache misses. But as I say, I'd map the file, and if that's fastest who cares about the others? ;-)
Steve Jessop
Oh, also I vaguely remember something about 32bit Windows not being particularly good at using over 2GB of RAM - it uses it, but there's a split between what it can use for apps and what only the kernel can use. Maybe that's just the virtual space, though, I don't really remember. For example if you have two apps running each using 1.5GB of memory, with 4GB RAM, can Win32 actually avoid swapping? You'd think so, but I'm not entirely sure.
Steve Jessop
Not actually true - when you allocate memory, Windows will only commit the memory, it won't actually allocate anything until you touch the pages by reading or writing to them.
Paul Betts
True, where I've said "allocating", I should have said "using".
Steve Jessop
Win32 often has two memory caps: one is the 2 GB virtual address space (per process) and one is the 4GB physical address space. The problem with the latter is that physical address space also includes memory reserved for PCIe cards, in particular videocards. A 512 MB videocard may shadow 1/8th of the 4GB RAM.
MSalters
And it is getting worse dramatically - I've got a research task outstanding because we're seriously concerned about people using 1.5GB video cards on 32bit Windows!
Andy Dent
A: 

As I see the situation, you either manage the paging yourself or let the operating system manage the paging for you. In most cases I would suggest letting the operating system handle the paging (use virtual memory). Since I have a distrust of MS operating systems, I cannnot recommend this technique, although your mileage may vary.

Thomas Matthews