mimalloc 2.1.9 does not prioritize allocating memory from huge pages
Hi, I specified the use of huge pages when using mimalloc 2.1.9, and the operating system has enough huge pages available. However, I noticed that upon program startup, 1 GB of memory was allocated from non-hugepage memory first. In version 2.1.7, mimalloc prioritizes allocating memory from hugepage memory until they are exhausted, after which it switches to non-hugepage memory.
The environment variable configuration is as follows: MIMALLOC_SHOW_STATS=1 MIMALLOC_SHOW_ERRORS=1 MIMALLOC_VERBOSE=1 MIMALLOC_RESERVE_HUGE_OS_PAGES=8 MIMALLOC_RESERVE_HUGE_OS_PAGES_AT=0 MIMALLOC_EAGER_COMMIT_DELAY=0
mi_debug_show_arenas: mimalloc: arena 0: 32 blocks of size 32MiB (in 1 fields) mimalloc: inuse blocks: mimalloc: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx mimalloc: total ('x'): 32 mimalloc: committed blocks: mimalloc: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx mimalloc: total ('x'): 32 mimalloc: arena 1: 256 blocks of size 32MiB (in 4 fields) , pinned mimalloc: inuse blocks: mimalloc: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.............................. mimalloc: ................................................................ mimalloc: ................................................................ mimalloc: ................................................................ mimalloc: total ('x'): 34 mimalloc: total inuse blocks : 66
Ah I see. I changed the default behavior just before the release -- ouch. Can you try if it is different if you set MIMALLOC_ALLOW_LARGE_OS_PAGES=1 ? Currently, there are 3 modes on Linux based systems:
- 0 : don't allow large OS pages at all (unless explicitly reserved through huge pages)
- 1 : actively try to use large OS pages (2 MiB). Only use huge pages when explicitly requested (by reserving huge pages).
- 2 : allow large OS pages but only through
madvisemeaning it will use large OS pages when THP is enabled on the system.
In all cases it seems that huge OS pages are only used if explicitly reserved. The reasoning is that using a huge page is a bit "bad" as that memory cannot be shared among other processes or swapped to disk -- so it should only be used if explicitly requested.
I wonder though why you see the initial arena being allocated with huge pages .. it means there is an allocation before the huge arena is reserved?
Ah I see. I changed the default behavior just before the release -- ouch. Can you try if it is different if you set
MIMALLOC_ALLOW_LARGE_OS_PAGES=1? Currently, there are 3 modes on Linux based systems:
- 0 : don't allow large OS pages at all (unless explicitly reserved through huge pages)
- 1 : actively try to use large OS pages (2 MiB). Only use huge pages when explicitly requested (by reserving huge pages).
- 2 : allow large OS pages but only through
madvisemeaning it will use large OS pages when THP is enabled on the system.In all cases it seems that huge OS pages are only used if explicitly reserved. The reasoning is that using a huge page is a bit "bad" as that memory cannot be shared among other processes or swapped to disk -- so it should only be used if explicitly requested.
I wonder though why you see the initial arena being allocated with huge pages .. it means there is an allocation before the huge arena is reserved?
The following is the log printed during the startup phase of mimaloc. When specifying the use of 8G of huge page memory, it first allocated 1G of normal memory.
mimalloc: option 'show_errors': 1 mimalloc: option 'show_stats': 1 mimalloc: option 'verbose': 1 mimalloc: option 'eager_commit': 1 mimalloc: option 'arena_eager_commit': 2 mimalloc: option 'purge_decommits': 1 mimalloc: option 'allow_large_os_pages': 2 mimalloc: option 'reserve_huge_os_pages': 8 mimalloc: option 'reserve_huge_os_pages_at': 0 mimalloc: option 'reserve_os_memory': 0 KiB mimalloc: option 'deprecated_segment_cache': 0 mimalloc: option 'deprecated_page_reset': 0 mimalloc: option 'abandoned_page_purge': 0 mimalloc: option 'deprecated_segment_reset': 0 mimalloc: option 'eager_commit_delay': 0 mimalloc: option 'purge_delay': 10 mimalloc: option 'use_numa_nodes': 0 mimalloc: option 'disallow_os_alloc': 0 mimalloc: option 'os_tag': 100 mimalloc: option 'max_errors': 32 mimalloc: option 'max_warnings': 32 mimalloc: option 'max_segment_reclaim': 10 mimalloc: option 'destroy_on_exit': 0 mimalloc: option 'arena_reserve': 1048576 KiB mimalloc: option 'arena_purge_mult': 10 mimalloc: option 'purge_extend_delay': 1 mimalloc: option 'abandoned_reclaim_on_free': 0 mimalloc: option 'disallow_arena_alloc': 0 mimalloc: option 'retry_on_oom': 400 mimalloc: option 'visit_abandoned': 0 mimalloc: option 'guarded_min': 0 mimalloc: option 'guarded_max': 1073741824 mimalloc: option 'guarded_precise': 0 mimalloc: option 'guarded_sample_rate': 0 mimalloc: option 'guarded_sample_seed': 0 mimalloc: option 'target_segments_per_thread': 0 mimalloc: process init: 0x7FAE415AA740 mimalloc: using 2 numa regions mimalloc: reserved 1048576 KiB memory //Does this indicate that it first allocated 1G of normal memory? mimalloc: secure level: 0 mimalloc: mem tracking: none mimalloc: numa node 0: reserved 8 GiB huge pages (of the 8 GiB requested)
If memory allocation is strictly limited to huge page memory, the program will fail to allocate memory in case of an overflow during runtime. Therefore, I want mimalloc to prioritize allocating from huge pages (for performance reasons) but allow it to fall back to normal memory if huge page memory is exhausted during runtime. In version 2.1.7, mimalloc's behavior aligns with this requirement. In version 2.1.9, is there any explicit configuration to achieve the same effect?
Ah I see. I changed the default behavior just before the release -- ouch. Can you try if it is different if you set
MIMALLOC_ALLOW_LARGE_OS_PAGES=1? Currently, there are 3 modes on Linux based systems:
- 0 : don't allow large OS pages at all (unless explicitly reserved through huge pages)
- 1 : actively try to use large OS pages (2 MiB). Only use huge pages when explicitly requested (by reserving huge pages).
- 2 : allow large OS pages but only through
madvisemeaning it will use large OS pages when THP is enabled on the system.In all cases it seems that huge OS pages are only used if explicitly reserved. The reasoning is that using a huge page is a bit "bad" as that memory cannot be shared among other processes or swapped to disk -- so it should only be used if explicitly requested.
I wonder though why you see the initial arena being allocated with huge pages .. it means there is an allocation before the huge arena is reserved?
I try MIMALLOC_ALLOW_LARGE_OS_PAGES=1 but the result still didn't change.
In all cases it seems that huge OS pages are only used if explicitly reserved. The reasoning is that using a huge page is a bit "bad" as that memory cannot be shared among other processes or swapped to disk -- so it should only be used if explicitly requested.
Hi @daanx, is it possible adding an option that allows:
- Prioritize reserved huge OS pages (1GiB).
- If exhausted, fall back to large OS pages (2 MiB).
or could you point out how I can achieve that?
Besides, is there any function to easily malloc directly into huge OS pages? (I searched through the docs but failed finding one.)