Skip to content

Commit

Permalink
put node count in timer
Browse files Browse the repository at this point in the history
  • Loading branch information
Heiaha committed Nov 30, 2024
1 parent be535ef commit 5b3def6
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 67 deletions.
44 changes: 15 additions & 29 deletions src/search.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,9 @@ use super::types::*;

pub struct Search<'a> {
id: u16,
stop: bool,
sel_depth: Ply,
timer: Timer,
tt: &'a TT,
nodes: u64,
move_sorter: MoveSorter,
}

Expand All @@ -24,9 +22,7 @@ impl<'a> Search<'a> {
id,
timer,
tt,
stop: false,
sel_depth: 0,
nodes: 0,
move_sorter: MoveSorter::new(),
}
}
Expand Down Expand Up @@ -55,11 +51,7 @@ impl<'a> Search<'a> {
return Some(moves[0].m);
}

while !self.stop
&& self.timer.start_check(depth)
&& !Self::is_checkmate(value)
&& depth < Depth::MAX
{
while self.timer.start_check(depth) && !Self::is_checkmate(value) && depth < Depth::MAX {
(best_move, value) = self.search_root(&mut board, depth, alpha, beta);

///////////////////////////////////////////////////////////////////
Expand All @@ -79,7 +71,7 @@ impl<'a> Search<'a> {
beta = Self::MATE;
} else {
// Only print info if we're in the main thread
if self.id == 0 && !self.stop {
if self.id == 0 && !self.timer.local_stop() {
best_move.inspect(|&m| self.print_info(&mut board, depth, m, value));
}
alpha = value - Self::ASPIRATION_WINDOW;
Expand Down Expand Up @@ -139,7 +131,7 @@ impl<'a> Search<'a> {
}
board.pop();

if self.stop {
if self.timer.local_stop() {
break;
}

Expand All @@ -163,7 +155,7 @@ impl<'a> Search<'a> {
}
});

if !self.stop {
if !self.timer.local_stop() {
self.tt.insert(board, depth, alpha, best_move, Bound::Exact);
}
(best_move, alpha)
Expand All @@ -177,11 +169,6 @@ impl<'a> Search<'a> {
mut beta: Value,
ply: Ply,
) -> Value {
if self.stop || self.timer.stop_check() {
self.stop = true;
return 0;
}

///////////////////////////////////////////////////////////////////
// Mate distance pruning - will help reduce
// some nodes when checkmate is near.
Expand All @@ -190,7 +177,6 @@ impl<'a> Search<'a> {
alpha = alpha.max(-mate_value);
beta = beta.min(mate_value - 1);
if alpha >= beta {
self.nodes += 1;
return alpha;
}

Expand All @@ -211,7 +197,9 @@ impl<'a> Search<'a> {
return self.q_search(board, alpha, beta, ply);
}

self.nodes += 1;
if self.timer.stop_check() {
return 0;
}

if board.is_draw() {
return 0;
Expand Down Expand Up @@ -261,7 +249,7 @@ impl<'a> Search<'a> {
board.push_null();
let value = -self.search(board, depth - r - 1, -beta, -beta + 1, ply);
board.pop_null();
if self.stop {
if self.timer.local_stop() {
return 0;
}
if value >= beta {
Expand Down Expand Up @@ -328,7 +316,7 @@ impl<'a> Search<'a> {

board.pop();

if self.stop {
if self.timer.local_stop() {
return 0;
}

Expand Down Expand Up @@ -363,7 +351,7 @@ impl<'a> Search<'a> {
}
}

if !self.stop {
if !self.timer.local_stop() {
best_move = best_move.or_else(|| {
if moves.len() > 0 {
Some(moves[0].m)
Expand All @@ -384,13 +372,10 @@ impl<'a> Search<'a> {
mut beta: Value,
ply: Ply,
) -> Value {
if self.stop || self.timer.stop_check() {
self.stop = true;
if self.timer.stop_check() {
return 0;
}

self.nodes += 1;

if board.is_draw() {
return 0;
}
Expand Down Expand Up @@ -439,7 +424,7 @@ impl<'a> Search<'a> {
let value = -self.q_search(board, -beta, -alpha, ply + 1);
board.pop();

if self.stop {
if self.timer.local_stop() {
return 0;
}

Expand Down Expand Up @@ -533,15 +518,16 @@ impl<'a> Search<'a> {
};

let elapsed = self.timer.elapsed();
let nodes = self.timer.nodes();

println!("info currmove {m} depth {depth} seldepth {sel_depth} time {time} score {score_str} nodes {nodes} nps {nps} pv {pv}",
m = m,
depth = depth,
sel_depth = self.sel_depth,
time = elapsed.as_millis(),
score_str = score_str,
nodes = self.nodes,
nps = (self.nodes as f64 / elapsed.as_secs_f64()) as u64,
nodes = nodes,
nps = (nodes as f64 / elapsed.as_secs_f64()) as u64,
pv = self.get_pv(board, depth));
}

Expand Down
11 changes: 10 additions & 1 deletion src/search_master.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::sync;
use std::sync::atomic::*;
use std::sync::mpsc::Receiver;
use std::sync::Arc;
use std::thread;
use std::time::Duration;

Expand Down Expand Up @@ -79,11 +80,18 @@ impl SearchMaster {

fn go(&mut self, time_control: TimeControl) {
self.stop.store(false, Ordering::SeqCst);
let nodes = Arc::new(AtomicU64::new(0));

let best_move = thread::scope(|s| {
// Create main search thread with the actual time control. This thread controls self.stop.
let mut main_search_thread = Search::new(
Timer::new(&self.board, time_control, self.stop.clone(), self.overhead),
Timer::new(
&self.board,
time_control,
self.stop.clone(),
nodes.clone(),
self.overhead,
),
&self.tt,
0,
);
Expand All @@ -96,6 +104,7 @@ impl SearchMaster {
&thread_board,
TimeControl::Infinite,
self.stop.clone(),
nodes.clone(),
self.overhead,
),
&self.tt,
Expand Down
85 changes: 48 additions & 37 deletions src/timer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ use super::moov::*;
use super::types::*;
use crate::piece::*;
use regex::{Match, Regex};
use std::sync;
use std::sync::atomic::AtomicBool;
use std::sync::atomic::{AtomicBool, AtomicU64, Ordering};
use std::sync::{Arc, LazyLock};
use std::time::{Duration, Instant};

Expand Down Expand Up @@ -142,7 +141,9 @@ static GO_RE: LazyLock<Regex> = LazyLock::new(|| {
pub struct Timer {
control: TimeControl,
start_time: Instant,
stop: Arc<AtomicBool>,
global_stop: Arc<AtomicBool>,
local_stop: bool,
nodes: Arc<AtomicU64>,
times_checked: u64,
time_target: Duration,
time_maximum: Duration,
Expand All @@ -155,6 +156,7 @@ impl Timer {
board: &Board,
control: TimeControl,
stop: Arc<AtomicBool>,
nodes: Arc<AtomicU64>,
overhead: Duration,
) -> Self {
let (time_target, time_maximum) = if let TimeControl::Variable { .. } = control {
Expand All @@ -165,7 +167,9 @@ impl Timer {

Self {
start_time: Instant::now(),
stop,
global_stop: stop,
local_stop: false,
nodes,
control,
overhead,
time_target,
Expand All @@ -192,22 +196,21 @@ impl Timer {
Color::Black => (btime, binc),
};

let mtg = moves_to_go.unwrap_or_else(|| {
(Self::MTG_INTERCEPT
+ Self::MTG_EVAL_WEIGHT * (board.simple_eval().abs() as f32)
+ Self::MTG_MOVE_WEIGHT * (board.fullmove_number() as f32))
.ceil()
.max(1.0) as u32
});
let mtg = moves_to_go.unwrap_or(40);

let time_target = time.min(time / mtg + inc.unwrap_or(Duration::ZERO));
let time_maximum = time_target + (time - time_target) / 4;

(time_target, time_maximum)
}

pub fn start_check(&self, depth: Depth) -> bool {
if self.stop.load(sync::atomic::Ordering::Relaxed) {
pub fn start_check(&mut self, depth: Depth) -> bool {
if self.local_stop {
return false;
}

if self.global_stop.load(Ordering::Relaxed) {
self.nodes.fetch_add(self.times_checked, Ordering::Relaxed);
return false;
}

Expand All @@ -225,54 +228,65 @@ impl Timer {
};

if !start {
self.stop.store(true, sync::atomic::Ordering::Relaxed);
self.local_stop = true;
self.global_stop.store(true, Ordering::Relaxed);
}
start
}

pub fn stop_check(&mut self) -> bool {
if self.local_stop {
return true;
}

self.times_checked += 1;

let should_check = self.times_checked & Self::CHECK_FLAG == 0;
if self.times_checked < Self::CHECK_FREQ {
return false;
}

let nodes = self.nodes.fetch_add(self.times_checked, Ordering::Relaxed);
self.times_checked = 0;

if should_check && self.stop.load(sync::atomic::Ordering::Relaxed) {
if self.global_stop.load(Ordering::Relaxed) {
self.local_stop = true;
return true;
}

let stop = match self.control {
TimeControl::Infinite => false,
TimeControl::FixedDuration(duration) => {
if should_check {
self.elapsed() + self.overhead >= duration
} else {
false
}
}
TimeControl::Variable { .. } => {
if should_check {
self.elapsed() + self.overhead >= self.time_maximum
} else {
false
}
}
TimeControl::FixedDuration(duration) => self.elapsed() + self.overhead >= duration,
TimeControl::Variable { .. } => self.elapsed() + self.overhead >= self.time_maximum,
TimeControl::FixedDepth(_) => false,
TimeControl::FixedNodes(nodes) => self.times_checked >= nodes,
TimeControl::FixedNodes(stop_nodes) => nodes >= stop_nodes,
};

if stop {
self.stop.store(true, sync::atomic::Ordering::Relaxed);
self.nodes.fetch_add(self.times_checked, Ordering::Relaxed);
self.local_stop = true;
self.global_stop.store(true, Ordering::Relaxed);
}

stop
}

pub fn stop(&mut self) {
self.stop.store(true, sync::atomic::Ordering::SeqCst);
self.local_stop = true;
self.global_stop.store(true, Ordering::SeqCst);
}

pub fn elapsed(&self) -> Duration {
self.start_time.elapsed()
}

pub fn nodes(&self) -> u64 {
self.nodes.load(Ordering::Relaxed) + self.times_checked
}

pub fn local_stop(&self) -> bool {
self.local_stop
}

pub fn update(&mut self, best_move: Option<Move>) {
if self
.last_best_move
Expand All @@ -286,8 +300,5 @@ impl Timer {
}

impl Timer {
const CHECK_FLAG: u64 = 0x1000 - 1;
const MTG_INTERCEPT: f32 = 52.52;
const MTG_EVAL_WEIGHT: f32 = -0.01833;
const MTG_MOVE_WEIGHT: f32 = -0.4657;
const CHECK_FREQ: u64 = 4096;
}

0 comments on commit 5b3def6

Please sign in to comment.