Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mimalloc 2.1.9 does not prioritize allocating memory from huge pages #983

Open
benqwu opened this issue Jan 6, 2025 · 4 comments
Open

Comments

@benqwu
Copy link

benqwu commented Jan 6, 2025

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

@benqwu
Copy link
Author

benqwu commented Jan 6, 2025

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

@daanx
Copy link
Collaborator

daanx commented Jan 6, 2025

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 madvise meaning 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?

@benqwu
Copy link
Author

benqwu commented Jan 7, 2025

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 madvise meaning 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?

@benqwu
Copy link
Author

benqwu commented Jan 8, 2025

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 madvise meaning 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants