
Hello Duncan, Thursday, April 21, 2005, 5:36:28 PM, you wrote: DC> On Thu, 2005-04-21 at 10:57 +0100, Simon Marlow wrote:
I mentioned madvise() above: this is a compromise solution which involves telling the kernel that the data in memory is not relevant, but doesn't actually free the memory. The kernel is free to discard the pages if memory gets tight, without actually swapping them to disk. When the memory is faulted in again, it gets filled with zeros. This is ideal for copying GC: you madvise() the semispace you just copied from, because it contains junk.
IIRC, madvise() is a BSD-ish interface, but other OSs probably have similar facilities.
DC> Linux and Solaris have this interface (Solaris with possibly different DC> flags MADV_DONTNEED/MADV_FREE). DC> And there is also a standardised posix_madvise() (that no-one seems to DC> support!) DC> That probably covers it for unixy(linux,solaris,*bsd,darwin) systems. DC> Don't know about win32. it seems that madvise() is an ideal solution for systems that support this for other OS'es we can use unmap+map. the drawback is that OS wastes time filling this reallocated memory with zeros (at least that does VirtualFree+VirtualAlloc under WIN XP), so this will add 5-10% to cost of major GCs. as i can see in GC.c, we can't free old memory before allocating all new one, so in case of physical memory shortage this algorithm will be worse than compacting? also while viewing MBlock.c i wonder why you are aligning megablocks to megabyte boundary - may be 8-byte aligning would be enough? megablocks are never copied or allocated as whole, and even in this case aligning to CPU cache line boundary will be enough another strange thins is what under win32 (and only win32) without "+RTS -M" option we are restricted to 256 Mbytes of heap. see at this code:
if ( (base_non_committed == 0) || (next_request + size > end_non_committed) ) { if (base_non_committed) { /* Tacky, but if no user-provided -M option is in effect, * set it to the default (==256M) in time for the heap overflow PSA. */ if (RtsFlags.GcFlags.maxHeapSize == 0) { RtsFlags.GcFlags.maxHeapSize = size_reserved_pool / BLOCK_SIZE; } heapOverflow(); }
i think it must be:
if ( (base_non_committed == 0) || (next_request + size > end_non_committed) ) { if (base_non_committed && RtsFlags.GcFlags.maxHeapSize) { heapOverflow(); }
in order to allow programs without "+RTS -M" option allocate more than one 256 mbyte chunk -- Best regards, Bulat mailto:bulatz@HotPOP.com