From dc0e9bcc5866e58da8cce0d4076b5b8f91fd8277 Mon Sep 17 00:00:00 2001 From: Adarsh Das Date: Tue, 16 Jun 2026 23:51:04 +0530 Subject: [PATCH] Implement huge page for Continuation and Continuation correction history STC SMP Elo | 2.31 +- 1.85 (95%) SPRT | 5.0+0.05s Threads=8 Hash=256MB LLR | 2.91 (-2.25, 2.89) [0.00, 4.00] Games | N: 32202 W: 8023 L: 7809 D: 16370 Penta | [32, 3587, 8667, 3765, 50] https://recklesschess.space/test/15269/ Bench: 3204302 --- src/history.rs | 76 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 72 insertions(+), 4 deletions(-) diff --git a/src/history.rs b/src/history.rs index bd879600b..b8aa4c613 100644 --- a/src/history.rs +++ b/src/history.rs @@ -6,6 +6,74 @@ type FromToHistory = [[T; 64]; 64]; type PieceToHistory = [[T; 64]; 13]; type ContinuationHistoryType = [[[[PieceToHistory; 64]; 13]; 2]; 2]; +struct HugeBox { + ptr: std::ptr::NonNull, +} + +unsafe impl Send for HugeBox {} +unsafe impl Sync for HugeBox {} + +impl HugeBox { + fn new_zeroed() -> Self { + #[cfg(target_os = "linux")] + let ptr = unsafe { + use libc::{MADV_HUGEPAGE, MAP_ANONYMOUS, MAP_FAILED, MAP_PRIVATE, PROT_READ, PROT_WRITE, madvise, mmap}; + let size = std::mem::size_of::(); + assert!(size > 0, "HugeBox requires a non-zero-sized type"); + let p = mmap(std::ptr::null_mut(), size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if p == MAP_FAILED { + std::alloc::handle_alloc_error(std::alloc::Layout::new::()); + } + madvise(p, size, MADV_HUGEPAGE); + std::ptr::NonNull::new_unchecked(p.cast::()) + }; + + #[cfg(not(target_os = "linux"))] + let ptr = unsafe { + let layout = std::alloc::Layout::new::(); + let p = std::alloc::alloc_zeroed(layout); + if p.is_null() { + std::alloc::handle_alloc_error(layout); + } + std::ptr::NonNull::new_unchecked(p.cast::()) + }; + + HugeBox { ptr } + } +} + +impl std::ops::Deref for HugeBox { + type Target = T; + fn deref(&self) -> &T { + unsafe { self.ptr.as_ref() } + } +} + +impl std::ops::DerefMut for HugeBox { + fn deref_mut(&mut self) -> &mut T { + unsafe { self.ptr.as_mut() } + } +} + +impl Drop for HugeBox { + fn drop(&mut self) { + #[cfg(target_os = "linux")] + { + let size = std::mem::size_of::(); + assert!(size > 0, "HugeBox requires a non-zero-sized type"); + unsafe { + libc::munmap(self.ptr.as_ptr().cast(), size); + } + } + + #[cfg(not(target_os = "linux"))] + unsafe { + let layout = std::alloc::Layout::new::(); + std::alloc::dealloc(self.ptr.as_ptr().cast(), layout); + } + } +} + fn apply_bonus(entry: &mut i16, bonus: i32) { let bonus = bonus.clamp(-MAX, MAX); *entry += (bonus - bonus.abs() * (*entry) as i32 / MAX) as i16; @@ -101,7 +169,7 @@ impl Default for CorrectionHistory { pub struct ContinuationCorrectionHistory { // [in_check][capture][piece][to][piece][to] - entries: Box, + entries: HugeBox, } impl ContinuationCorrectionHistory { @@ -125,13 +193,13 @@ impl ContinuationCorrectionHistory { impl Default for ContinuationCorrectionHistory { fn default() -> Self { - Self { entries: zeroed_box() } + Self { entries: HugeBox::new_zeroed() } } } pub struct ContinuationHistory { // [in_check][capture][piece][to][piece][to] - entries: Box, + entries: HugeBox, } impl ContinuationHistory { @@ -155,7 +223,7 @@ impl ContinuationHistory { impl Default for ContinuationHistory { fn default() -> Self { - Self { entries: zeroed_box() } + Self { entries: HugeBox::new_zeroed() } } }