Skip to content

Commit 4eb1689

Browse files
committed
add option to make fresh arena allocation associate with a local numa node
1 parent 125099f commit 4eb1689

3 files changed

Lines changed: 11 additions & 4 deletions

File tree

include/mimalloc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -483,6 +483,7 @@ typedef enum mi_option_e {
483483
mi_option_allow_thp, // allow transparent huge pages? (=1) (on Android =0 by default). Set to 0 to disable THP for the process.
484484
mi_option_minimal_purge_size, // set minimal purge size (in KiB) (=0). By default set to either 64 or 2048 if THP is enabled.
485485
mi_option_arena_max_object_size, // set maximal object size that can be allocated in an arena (in KiB) (=2GiB on 64-bit).
486+
mi_option_arena_is_numa_local, // experimental
486487
_mi_option_last,
487488
// legacy option names
488489
mi_option_large_os_pages = mi_option_allow_large_os_pages,

src/arena.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,7 @@ static size_t mi_arena_start_idx(mi_heap_t* heap, size_t tseq, size_t arena_cycl
399399
const size_t hseq = heap->heap_seq;
400400
const size_t hcount = mi_atomic_load_relaxed(&heap->subproc->heap_count);
401401
if (arena_cycle <= 1) return 0;
402-
if (hseq==0 || hcount<=1) return (tseq % arena_cycle); // common for single heap programs
402+
if (hseq==0 || hcount<=1 || arena_cycle > 0x8FF) return (tseq % arena_cycle); // common for single heap programs
403403

404404
// spread heaps evenly among arena's, and then evenly for threads in their fraction
405405
size_t start;
@@ -410,8 +410,8 @@ static size_t mi_arena_start_idx(mi_heap_t* heap, size_t tseq, size_t arena_cycl
410410
start = (hseq % arena_cycle);
411411
}
412412
else {
413-
const size_t hspot = (hseq % hcount);
414-
start = (frac * hspot) / 256;
413+
const size_t hspot = (hseq % hcount);
414+
start = (frac * hspot) / 256; // (arena_cycle * (hseq % hcount)) / hcount
415415
if (frac >= 512) { // at least 2 arena's per heap?
416416
start = start + (tseq % (frac/256));
417417
}
@@ -1537,7 +1537,12 @@ static mi_arena_t* mi_arena_initialize(mi_subproc_t* subproc, void* start,
15371537
arena->is_exclusive = exclusive;
15381538
arena->slice_count = slice_count;
15391539
arena->info_slices = info_slices;
1540-
arena->numa_node = numa_node; // TODO: or get the current numa node if -1? (now it allows anyone to allocate on -1)
1540+
if (numa_node<0 && mi_option_is_enabled(mi_option_arena_is_numa_local)) {
1541+
arena->numa_node = _mi_os_numa_node();
1542+
}
1543+
else {
1544+
arena->numa_node = numa_node;
1545+
}
15411546
arena->purge_expire = 0;
15421547
arena->commit_fun = commit_fun;
15431548
arena->commit_fun_arg = commit_fun_arg;

src/options.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ static mi_option_desc_t mi_options[_mi_option_last] =
178178
{ 0, MI_OPTION_UNINIT, MI_OPTION(minimal_purge_size) }, // set minimal purge size (in KiB) (=0). Using 0 resolves to either 64 (or 2048 if `mi_option_allow_thp==2`).
179179
{ MI_DEFAULT_ARENA_MAX_OBJECT_SIZE,
180180
MI_OPTION_UNINIT, MI_OPTION(arena_max_object_size) }, // set maximal object size that can be allocated in an arena (in KiB) (=2GiB on 64-bit).
181+
{ 0, MI_OPTION_UNINIT, MI_OPTION(arena_is_numa_local) }, // associate local numa node with an initial arena allocation
181182
};
182183

183184
static void mi_option_init(mi_option_desc_t* desc);

0 commit comments

Comments
 (0)