-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Description
Describe the issue
The Stockfish engine's memory management code, specifically in src/memory.cpp and src/memory.h, contains hardcoded assumptions of a 4KB (4096 bytes) system page size. This primarily affects the aligned_large_pages_alloc function for non-Windows/non-Linux (or generic Linux fallback) code paths and related helper functions like make_unique_large_page.
Specific Locations:
-
aligned_large_pages_alloc(non-Windows/non-Linux path) insrc/memory.cpp:C++
#else // Not _WIN32 void* aligned_large_pages_alloc(size_t allocSize) { #if defined(__linux__) && !defined(__ANDROID__) constexpr size_t alignment = 2 * 1024 * 1024; // 2MB page size assumed #else constexpr size_t alignment = 4096; // <--- HERE: small page size assumed #endif // ... } #endifThis hardcoded
4096is problematic when the actual system page size is different (e.g., 16KB). -
static_assertinmake_unique_large_pageinsrc/memory.h:C++
template<typename T, typename... Args> std::enable_if_t<!std::is_array_v<T>, LargePagePtr<T>> make_unique_large_page(Args&&... args) { static_assert(alignof(T) <= 4096, // <--- HERE "aligned_large_pages_alloc() may fail for such a big alignment requirement of T"); // ... } // Similar assert for array versionThis reinforces the 4KB assumption.
Impact:
This hardcoding can lead to issues on systems with page sizes other than 4KB, particularly:
- Suboptimal Alignment: Memory may not be aligned to the true system page boundary (e.g., 16KB), potentially negating performance benefits of such alignment.
- Inefficiency: May lead to memory fragmentation or waste if the OS rounds allocations to the actual larger page size.
- Compatibility: This is particularly relevant for newer Android devices and NDKs (e.g., NDK r27+) which promote 16KB page alignment. NDK guidelines also state that the
PAGE_SIZEmacro might become undefined in 16KB mode, emphasizing the need to dynamically query page sizes. - The function name
aligned_large_pages_allocimplies alignment to a system-relevant page size, which may not be met with a hardcoded value.
Expected behavior
The memory allocation functions, especially aligned_large_pages_alloc, should dynamically determine the actual system page size at runtime and use this value for memory alignment when intending to align to "page size".
Specifically:
- The hardcoded
4096value used as a presumed page size should be replaced with a value obtained by callingsysconf(_SC_PAGESIZE)(on POSIX-compliant systems like Linux, Android, macOS) or a similar platform-specific API. - Memory allocations intended to be page-aligned should be aligned to this dynamically fetched, actual system page size (e.g., 4KB, 16KB, or other).
- The
static_assertinmake_unique_large_pageshould be re-evaluated. If it's meant to check against the page size, it needs to accommodate dynamic page sizes (perhaps by becoming a runtime check for unusually largealignof(T)or by using a more flexible compile-time constant if page size is constrained within a known set for targeted platforms). - Comments should reflect the dynamic nature of page size determination.
Steps to reproduce
This is a code architecture issue identified through code review, rather than a runtime bug reproducible with specific UCI commands. The issue becomes relevant on systems where the actual page size differs from the hardcoded 4KB assumption.
To observe the relevant code:
-
Review the
aligned_large_pages_allocfunction in
src/memory.cpp, specifically the
#elseblock for non-Windows, non-specific-Linux code paths.
C++
// memory.cpp, within aligned_large_pages_alloc #else // Not _WIN32 // ... #if defined(__linux__) && !defined(__ANDROID__) // ... #else constexpr size_t alignment = 4096; // Problematic line #endif -
Review the
static_assertconditions in
make_unique_large_pagein
src/memory.h.
C++
// memory.h, within make_unique_large_page static_assert(alignof(T) <= 4096, ...); -
Consider the execution path and memory alignment results if this code runs on a system with a 16KB page size (e.g., an Android device compiled with NDK r27+ targeting 16KB-aligned executables). The memory will be aligned to 4KB, not the system's actual 16KB page size.
Anything else?
Proposed Solution Details:
-
Use sysconf(_SC_PAGESIZE):
In src/memory.cpp, for POSIX-like systems (including Linux, Android, macOS), replace the hardcoded 4096 with a call to sysconf(_SC_PAGESIZE).
C++
#include <unistd.h> // For sysconf // Helper (can be placed appropriately) static size_t get_system_page_size() { long page_size_val = sysconf(_SC_PAGESIZE); if (page_size_val == -1) { // Fallback or error handling // For robustness, might log an error and return a default like 4096, // or throw, depending on desired error handling strategy. return 4096; } return static_cast<size_t>(page_size_val); } // In aligned_large_pages_alloc for the generic path: // ... #else // for the generic POSIX path alignment = get_system_page_size(); #endif // ... -
Re-evaluate static_assert:
The static_assert(alignof(T) <= 4096, ...) logic needs to be updated. Since page size is dynamic, a compile-time check against a fixed value is problematic.
- If
alignof(T)is generally expected to be small (e.g., <= 64 bytes), it will likely always be less than any system page size (4KB, 16KB, 64KB). The assert might be unnecessary or could check against a very generous maximum alignment ifalignof(T)could be extremely large for some types used with this allocator. - Alternatively, if
PAGE_SIZEbecomes available as a reliable compile-time constant in target build environments (especially NDK r27+ for 16KB mode), it could be used. Otherwise, this check might need to be a runtime check or be removed ifstd_aligned_allocis trusted to handle thealignof(T)passed to it.
- If
-
Windows Code Path: The Windows-specific code using
GetLargePageMinimum()andVirtualAllocseems generally fine as it queries system properties.
This change is crucial for future-proofing Stockfish, ensuring optimal performance on modern hardware (especially Android devices with 16KB pages), and adhering to evolving platform guidelines.
Operating system
Android