The attached patch is the next set of proposed changes to the memory management routines, with the copy-on-write logic removed.
Performance numbers on my 166-MHz Pentium (linux 2.2.18) for 5000-generation life.pasm are: Current CVS - 50.41 generations/second With this patch - 57.40 With COW & string_append - 65.43 The main features are: Revised 'live' marking system with removal of mark_X_unused functions Initial framework for dynamic allocation algorithms Incorporation of the free pools into the standard buffer header pool, to avoid special handling in compact_buffer_pool Details The 'live' flag is now only valid during a DOD run. It is cleared when an object is created and again at the end of the DOD run. This means that the overhead of a separate pass through the pools to clear the flag at the start of a DOD run is eliminated. For PMCs, the next_for_GC field is treated in the same way - initialised to NULL in new_pmc_header, and reset to NULL in free_unused_PMCs. The 'on_free_list' flag is used instead to identify live buffers during memory compaction. The initial allocation for each pool has been reduced from 128 to 16, this is obviously an arbitrary number, but only once we have a large set of benchmarks will be able to calculate the best 'average' values. However, each time a new allocation is required, the number of units allocated is increased; controlled by parameters currently defined at the top of resources.c. Again, these numbers just seemed reasonable in some very simple tests, and need more tuning. Also, instead of waiting for a pool to be empty before refilling it, each pool has a replenishment level, at which a new block will be allocated. These replenishment levels currently start at half the original pool size, and increase with every allocation, but at a slower rate. This helps reduce the thrashing that can otherwise occur when the pool oscillates between empty and almost empty. These rules are mainly to introduce the concept of dynamic response, hopefully suggestions/implementations of better algorithms will follow in due course. The free pool buffer headers were being held as independent Buffer structures within the Resource_Pool; this meant that they had to be separately handled in compact_buffer_pool, which looked a mess, and made it easy to forget things. They are now held as pointers, and allocated through the normal procedure, except for the first one. The normal buffer pool's free pool header is first allocated from system memory, so that the pool can be initialised. Then, a new buffer header is allocated in the standard way, and takes over from the initial one, which is returned to the system. This change required the addition of an 'immune' flag for buffers. I suspect that Steve's recent changes, which make variable-sized buffer headers simple, will allow other internal structures to be handled using the buffer mechanism, and so the immune flag could be generally useful anyway. [Steve - it seems to me that the 'normal' buffer pool should just be replaced by the size 0 pool in your new system? I would think twice about incorporating strings, as that might complicate COW, if it ever happens.] -- Peter Gibbs EmKel Systems
combined.patch
Description: Binary data