PREV UP next StackThreads/MP: version 0.77 User's Guide

4.2.2: Creating A Region

When a region is created by st_make_region(), free lists are empty. Therefore, allocations from a region gradually grow its free lists, occasionally calling the underlying allocator. As is mentioned in the beginning of this section, it may still suffer performance of parallel sections, if the underlying allocator serializes all allocation requests. One idea is to use SGC as the underlying allocator. If you want to (or must) deal with this problem with the default malloc, you may pre-allocate some chunks upon region creation. Here are the full APIs for creating regions. st_make_region() is repeated for completeness.

        #include <ralloc.h>
@        st_region_t 
@        st_make_region_aux(chunk_size, init_size,
@                           pre_alloc_option, alloc, free);
@        st_region_t 
@        st_make_region_highly_concurrent_1(init_size, alloc, free);
@        st_region_t 
@        st_make_region_highly_concurrent(size);
@        st_region_t 
@        st_make_region();

With st_make_region_aux, you can control all the parameters. chunk_size is the size of a single chunk. It is the unit of allocation via the underlying allocator. alloc and free specify the underlying allocator; alloc is a function that behaves similarly to the malloc in libc, whereas free is a function that behaves similarly to free in libc.

init_size specifies the initial size of the region in bytes. Each worker allocates init_size/N bytes from the underlying allocator when it makes the first allocation from the region, where N is the number of workers in the worker group the calling worker belongs to. The net effect is that, the region soon becomes approximately init_size bytes in total as long as all workers will soon attempt to allocate at least one byte from this region. If you can approximate the total size of allocations that are going to be made from the region, you can give this value to avoid occasionally calling underlying allocators in parallel sections.

pre_alloc_option specifies whether this first allocation is made at the region's creation time. When pre_alloc_option == st_region_pre_allocated_option_none, no pre-allocation is performed upon creation. Each worker allocates the specified bytes upon first allocation. When pre_alloc_option == st_region_pre_allocated_option_self, the calling worker allocates the specified bytes only for the calling worker. When pre_alloc_option == st_region_pre_allocated_option_all, the calling worker allocates the specified bytes for all the workers.

A commonly used combination is provided by st_make_region_highly_concurrent_1. It intends to be useful for regions from which many allocations are going to be made in a parallel section. It allocates init_size bytes upon creation and evenly distributes them to all the workers. st_make_region_highly_concurrent is a simple wrapper to st_make_region_highly_concurrent_1. It gives the value of a macro RG_ALLOC_FUNC and RG_FREE_FUNC to st_make_region_highly_concurrent_1 as the underlying alloc and free functions, respectively. Their default values are the system malloc and free, respectively, but you can override them before including ralloc.h. For example,

        #define RG_ALLOC my_malloc
@        #define RG_FREE my_free
@        #include <ralloc.h>