Skip to content

Commit c8f0a0e

Browse files
authored
Move cutoff_count and excluded from StackEntry, and change move_count for 32b align (#1049)
VSTC (non-reg, field removal) Elo | 1.21 +- 1.89 (95%) SPRT | 4.0+0.04s Threads=1 Hash=16MB LLR | 3.06 (-2.25, 2.89) [-2.75, 0.25] Games | N: 34278 W: 8853 L: 8734 D: 16691 Penta | [171, 3772, 9143, 3873, 180] https://recklesschess.space/test/15023/ VSTC (gainer with 32b align) Elo | 2.16 +- 1.56 (95%) SPRT | 4.0+0.04s Threads=1 Hash=16MB LLR | 3.36 (-2.25, 2.89) [0.00, 3.00] Games | N: 49774 W: 13059 L: 12750 D: 23965 Penta | [263, 5286, 13490, 5575, 273] https://recklesschess.space/test/15024/ No functional change. Bench: 2756239 Co-authored By: Shahin M. Shahin <peregrineshahin@gmail.com>
1 parent ee5ca6b commit c8f0a0e

4 files changed

Lines changed: 56 additions & 21 deletions

File tree

src/search.rs

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::{
44
evaluation::correct_eval,
55
movepick::{MovePicker, Stage},
66
stack::Stack,
7-
thread::{RootMove, Status, ThreadData},
7+
thread::{PlyArray, RootMove, Status, ThreadData},
88
time::Limits,
99
transposition::{Bound, TtDepth},
1010
types::{
@@ -125,6 +125,8 @@ pub fn start(td: &mut ThreadData, report: Report, thread_count: usize) {
125125

126126
loop {
127127
td.stack = Stack::new();
128+
td.cutoff_count = PlyArray::default();
129+
td.excluded = PlyArray::default();
128130
td.root_delta = beta - alpha;
129131

130132
// Root Search
@@ -269,7 +271,7 @@ fn search<NODE: NodeType>(
269271

270272
let stm = td.board.side_to_move();
271273
let in_check = td.board.in_check();
272-
let excluded = td.stack[ply].excluded.is_present();
274+
let excluded = td.excluded[ply].is_present();
273275

274276
if !NODE::ROOT && NODE::PV {
275277
td.pv_table.clear(ply as usize);
@@ -448,7 +450,7 @@ fn search<NODE: NodeType>(
448450
td.stack[ply].tt_pv = tt_pv;
449451
td.stack[ply].reduction = 0;
450452
td.stack[ply].move_count = 0;
451-
td.stack[ply + 2].cutoff_count = 0;
453+
td.cutoff_count[ply + 2] = 0;
452454

453455
// Quiet move ordering using eval difference
454456
if !NODE::ROOT && !in_check && !excluded && td.stack[ply - 1].mv.is_quiet() && is_valid(td.stack[ply - 1].eval) {
@@ -528,7 +530,7 @@ fn search<NODE: NodeType>(
528530
>= beta
529531
+ (-9 * depth + 108 * tt_pv as i32
530532
- 96 * improvement / 1024
531-
- 18 * (td.stack[ply + 1].cutoff_count < 2) as i32
533+
- 18 * (td.cutoff_count[ply + 1] < 2) as i32
532534
+ 320)
533535
.max(2)
534536
&& ply as i32 >= td.nmp_min_ply
@@ -600,7 +602,7 @@ fn search<NODE: NodeType>(
600602
break;
601603
}
602604

603-
if mv == td.stack[ply].excluded {
605+
if mv == td.excluded[ply] {
604606
continue;
605607
}
606608

@@ -653,10 +655,10 @@ fn search<NODE: NodeType>(
653655
let singular_beta = tt_score - singular_margin;
654656
let singular_depth = (depth - 1) / 2;
655657

656-
td.stack[ply].excluded = tt_move;
658+
td.excluded[ply] = tt_move;
657659
td.stack[ply].mv = Move::NULL;
658660
singular_score = search::<NonPV>(td, singular_beta - 1, singular_beta, singular_depth, cut_node, ply);
659-
td.stack[ply].excluded = Move::NULL;
661+
td.excluded[ply] = Move::NULL;
660662
td.stack[ply].tt_pv = tt_pv;
661663

662664
if td.shared.status.get() == Status::STOPPED {
@@ -705,7 +707,7 @@ fn search<NODE: NodeType>(
705707
let mut tt_move_score = Score::NONE;
706708

707709
while let Some(mv) = move_picker.next::<NODE>(td, skip_quiets, ply) {
708-
if mv == td.stack[ply].excluded {
710+
if mv == td.excluded[ply] {
709711
continue;
710712
}
711713

@@ -732,7 +734,8 @@ fn search<NODE: NodeType>(
732734
&& !td.board.is_direct_check(mv)
733735
&& is_quiet
734736
&& !is_win(beta)
735-
&& move_count >= (2697 + 77 * improvement / 16 + 1510 * depth * depth + 70 * history / 1024) / 1024
737+
&& move_count as i32
738+
>= (2697 + 77 * improvement / 16 + 1510 * depth * depth + 70 * history / 1024) / 1024
736739
{
737740
skip_quiets = true;
738741
continue;
@@ -838,7 +841,7 @@ fn search<NODE: NodeType>(
838841
reduction -= 939;
839842
}
840843

841-
if td.stack[ply + 1].cutoff_count > 2 {
844+
if td.cutoff_count[ply + 1] > 2 {
842845
reduction += 992;
843846
reduction += 384 * (!NODE::PV && !cut_node) as i32;
844847
}
@@ -901,7 +904,7 @@ fn search<NODE: NodeType>(
901904
reduction += (402 - 232 * improvement / 128).min(1426);
902905
}
903906

904-
if td.stack[ply + 1].cutoff_count > 2 {
907+
if td.cutoff_count[ply + 1] > 2 {
905908
reduction += 1454;
906909
reduction += 256 * (!NODE::PV && !cut_node) as i32;
907910
}
@@ -995,7 +998,7 @@ fn search<NODE: NodeType>(
995998

996999
if score >= beta {
9971000
bound = Bound::Lower;
998-
td.stack[ply].cutoff_count += 1;
1001+
td.cutoff_count[ply] += 1;
9991002
break;
10001003
}
10011004

@@ -1074,7 +1077,7 @@ fn search<NODE: NodeType>(
10741077
let prior_move = td.stack[ply - 1].mv;
10751078
if prior_move.is_quiet() {
10761079
let factor = 88
1077-
+ (17 * td.stack[ply - 1].move_count).min(229)
1080+
+ (17 * td.stack[ply - 1].move_count as i32).min(229)
10781081
+ 110 * (prior_move == td.stack[ply - 1].tt_move) as i32
10791082
+ 144 * (!in_check && best_score <= eval - 97) as i32
10801083
+ 306 * (is_valid(td.stack[ply - 1].eval) && best_score <= -td.stack[ply - 1].eval - 136) as i32;

src/stack.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,9 @@ pub struct StackEntry {
3737
pub mv: Move,
3838
pub piece: Piece,
3939
pub eval: i32,
40-
pub excluded: Move,
4140
pub tt_move: Move,
4241
pub tt_pv: bool,
43-
pub cutoff_count: i32,
44-
pub move_count: i32,
42+
pub move_count: u16,
4543
pub reduction: i32,
4644
pub conthist: *mut [[i16; 64]; 13],
4745
pub contcorrhist: *mut [[i16; 64]; 13],
@@ -55,10 +53,8 @@ impl Default for StackEntry {
5553
mv: Move::NULL,
5654
piece: Piece::None,
5755
eval: Score::NONE,
58-
excluded: Move::NULL,
5956
tt_move: Move::NULL,
6057
tt_pv: false,
61-
cutoff_count: 0,
6258
move_count: 0,
6359
reduction: 0,
6460
conthist: std::ptr::null_mut(),

src/thread.rs

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1-
use std::sync::{
2-
Arc,
3-
atomic::{AtomicBool, AtomicU32, AtomicU64, AtomicUsize, Ordering},
1+
use std::{
2+
ops::{Index, IndexMut},
3+
sync::{
4+
Arc,
5+
atomic::{AtomicBool, AtomicU32, AtomicU64, AtomicUsize, Ordering},
6+
},
47
};
58

69
use crate::{
@@ -132,6 +135,29 @@ impl Default for SharedContext {
132135
}
133136
}
134137

138+
pub struct PlyArray<T, const N: usize> {
139+
data: [T; N],
140+
}
141+
142+
impl<T, const N: usize> Index<isize> for PlyArray<T, N> {
143+
type Output = T;
144+
fn index(&self, index: isize) -> &T {
145+
&self.data[(index + 8) as usize]
146+
}
147+
}
148+
149+
impl<T, const N: usize> IndexMut<isize> for PlyArray<T, N> {
150+
fn index_mut(&mut self, index: isize) -> &mut T {
151+
&mut self.data[(index + 8) as usize]
152+
}
153+
}
154+
155+
impl<T: Copy + Default, const N: usize> Default for PlyArray<T, N> {
156+
fn default() -> Self {
157+
Self { data: [T::default(); N] }
158+
}
159+
}
160+
135161
pub struct ThreadData {
136162
pub id: usize,
137163
pub shared: Arc<SharedContext>,
@@ -158,6 +184,8 @@ pub struct ThreadData {
158184
pub pv_index: usize,
159185
pub pv_start: usize,
160186
pub pv_end: usize,
187+
pub cutoff_count: PlyArray<i32, { MAX_PLY + 16 }>,
188+
pub excluded: PlyArray<Move, { MAX_PLY + 16 }>,
161189
}
162190

163191
impl ThreadData {
@@ -191,6 +219,8 @@ impl ThreadData {
191219
pv_index: 0,
192220
pv_start: 0,
193221
pv_end: 0,
222+
cutoff_count: PlyArray::default(),
223+
excluded: PlyArray::default(),
194224
}
195225
}
196226

src/types/moves.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,3 +159,9 @@ impl Move {
159159
output
160160
}
161161
}
162+
163+
impl Default for Move {
164+
fn default() -> Self {
165+
Move::NULL
166+
}
167+
}

0 commit comments

Comments
 (0)