Repository navigation
Add huge pages support for pymalloc #144319
Description
Activity
- added a commit that references this issue
on Jan 29, 2026 I like it. The bigger the better :-) It was unreasonably (to me) contentious when I pushed to boost arena size to !M (it was 256K). Hypothesized disasters never materialized ;-)
I'm thinking "probably the same here, except even higher potential to do good".
The one downside to any increase: because CPython never moves objects in memory, an arena can't be recycled so long as it contains any live object. A single long-lived float, e.g., could keep 2M of address space reserved "forever". But they can already do that with 1M arenas, and there's no particular evidence that it causes real problems.
Nice work! One thought I have is that maybe we should just bump the arena size to 2 MB on 64-bit platforms if bigpages are used or not. That would slightly simplify the code. On my Linux PC, just opening the REPL uses 6 arenas.
Reacted by Tim Peters+1 to boosting to 2M on all 64-bit boxes. obmalloc is careful not to touch memory before it actually needs to use it, carving up regions from low to high addresses , so there are just address-space reservations until needed.
- addedtype-featureA feature request or enhancementA feature request or enhancementinterpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)
on Jan 29, 2026 - added a commit that references this issue
on Jan 29, 2026 +1 to boosting to 2M on all 64-bit boxes. obmalloc is careful not to touch memory before it actually needs to use it, carving up regions from low to high addresses , so there are just address-space reservations until needed.
Will do this in another PR!
Reacted by Hash and Tim Peters@pablogsal While we're at it, maybe it makes sense to also enable
MADV_HUGEPAGE?madviseseems to be the default on Fedora Workstation and Ubuntu, at least according to this article:I've created a simple PR:
Hi @pablogsal, thanks for supporting this also on Windows ❤️.
Unfortunately, this won't work without additional adjustment, because according to https://learn.microsoft.com/en-us/windows/win32/memory/large-page-support
- the user must have the
SeLockMemoryPrivilegeprivilege - and it must be obtained by AdjustTokenPrivileges (once) in the process before calling VirtualAlloc
Hacking the necessary stuff right after
_PyConfig_Writeinpycore_init_runtime(and giving my user account the privilege in the Local Security Policy Microsoft Management Console) I get similar improvements you've presented for Linux.Considering also
- The memory is always read/write and nonpageable (always resident in physical memory).
and some more listed in the above link this might be a show-stopper?
- the user must have the
See also Raymond Chen's remarks that give some background information why on Windows huge pages are not paged to disk, etc.
- added a commit that references this issue
on Apr 30, 2026
pymalloc allocates small objects from contiguous regions called arenas. On 64-bit platforms each arena is 1 MiB, obtained via
mmap(MAP_PRIVATE|MAP_ANONYMOUS)and backed by 256 standard 4 KiB pages. Each page needs its own TLB entry, and the x86_64 dTLB only holds 64-128 entries for 4K pages, so a single arena already overflows TLB capacity, and any non-trivial Python program touches many arenas.Most modern operating systems support "huge pages": memory pages much larger than the default 4 KiB. On x86_64 Linux the standard huge page size is 2 MiB. A single 2 MiB huge page is covered by one TLB entry instead of 512 entries for the equivalent range of 4 KiB pages. This dramatically reduces TLB pressure for workloads that touch large contiguous allocations. On Linux, explicit huge pages are allocated via
mmapwith theMAP_HUGETLBflag (available since kernel 2.6.32) from a pre-reserved pool configured through/proc/sys/vm/nr_hugepages. On Windows, the equivalent isVirtualAllocwithMEM_LARGE_PAGES.I'd like to propose adding a
./configure --with-pymalloc-hugepagesoption that increasesARENA_BITSfrom 20 to 21 (1 MiB -> 2 MiB) and makes_PyMem_ArenaAlloc()trymmap(MAP_HUGETLB)first, falling back to regularmmapif the huge page pool is exhausted. On Windows the equivalent would beVirtualAlloc(MEM_LARGE_PAGES)with fallback._PyMem_ArenaFree()needs no changes sincemunmaphandles huge pages identically. All derived constants (ARENA_SIZE,MAX_POOLS_IN_ARENA, radix tree bit widths,nfp2lastasizing) adjust automatically fromARENA_BITS.The flag is opt-in and off by default.
MAP_HUGETLBrequires the kernel to have huge pages pre-allocated; without them the fallback path produces identical behavior to a non-hugepages build. On Linux, huge pages are managed through/proc/sys/vm/nr_hugepages. To allocate 128 huge pages (256 MiB on x86_64 where the default huge page size is 2 MiB):Each arena consumes one huge page. If the pool runs out, obmalloc falls back to regular 4K pages transparently.
I benchmarked on an i9-14900KS, Linux 6.18.3, GCC 15.2.1 on main with
nr_hugepages=128. Measured withperf stat -r 100usingcpu_corecounters. GC disabled during benchmarks.Wall-clock results:
dTLB miss reductions:
The perf command used per benchmark:
bench_obmalloc.py
Full reproduction:
Linked PRs
madvise(MADV_HUGEPAGE)#144353