improve Bot::think() api

This commit is contained in:
milo 2024-02-23 14:29:23 -05:00
parent a257743f8b
commit 5b0eda58ad
3 changed files with 12 additions and 22 deletions

View File

@ -59,7 +59,7 @@ const ITERS: u32 = 50_000;
fn think(iters: u32, weights: &Weights, matrix: &Mat, queue: Queue<'_>) -> Option<Piece> { fn think(iters: u32, weights: &Weights, matrix: &Mat, queue: Queue<'_>) -> Option<Piece> {
let mut bot = fish::bot::Bot::new(weights, matrix, queue); let mut bot = fish::bot::Bot::new(weights, matrix, queue);
bot.think_for(iters); bot.think(iters);
bot.suggest() bot.suggest()
} }

View File

@ -59,20 +59,12 @@ impl Bot {
} }
} }
/// Runs the bot for up to `gas` more iterations. An "iteration" is a unit of work /// Runs the bot, stopping it when it has done `max_iters` iterations since it was
/// that is intentionally kept vague, but should be proportional to the amount CPU /// first initialized. An "iteration" is an abstract unit of work that but should be
/// time. Iterations are deterministic, so similar versions of the engine will produce /// roughly proportional to the amount CPU time. Iterations are deterministic, so the
/// the same suggestions if run the for the same number of iterations. /// same version of the engine will produce the same suggestions if run the for the
pub fn think_for(&mut self, gas: u32) { /// same number of iterations.
// NOTICE: The actual number of iterations may slightly exceed the provided gas due to pub fn think(&mut self, max_iters: u32) {
// how the bot is currently structured. This shouldn't have a substantial impact over
// the long run since the overshoot will be very small in terms of CPU
// time.
//
// Runs will be deterministic as long as two runs end on the same *target*
// iterations on the last call to `think_for`, e.g. "bot.think_for(5000)" is the
// same as "bot.think_for(2500); bot.think_for(5000 - bot.iterations());"
let max_iters = self.iters + gas;
while self.iters < max_iters { while self.iters < max_iters {
let did_update = self.algorithm.step( let did_update = self.algorithm.step(
&self.arena, &self.arena,
@ -98,7 +90,7 @@ impl Bot {
} }
/// Returns the number of iterations done so far. /// Returns the number of iterations done so far.
pub fn iterations(&self) -> u32 { pub fn iters(&self) -> u32 {
self.iters self.iters
} }

View File

@ -388,12 +388,10 @@ fn run_simulation(
bot.start_instrumenting(); bot.start_instrumenting();
} }
// run the bot for a while; this could have been just `bot.think_for(iters)` but while bot.iters() < config.bot.iters {
// we limit the gas argument to prevent the thread from hanging too long while // limit iterations to ~25k to allow us to periodically check exit_early.
// thinking. let max_iters = config.bot.iters.min(bot.iters() + 25_000);
while bot.iterations() < config.bot.iters { bot.think(max_iters);
let gas = std::cmp::min(50_000, config.bot.iters - bot.iterations());
bot.think_for(gas);
// send a heartbeat back to the main thread to test if its still alive // send a heartbeat back to the main thread to test if its still alive
if tx.send(Msg::Heartbeat(id)).is_err() { if tx.send(Msg::Heartbeat(id)).is_err() {