Skip to content

Commit

Permalink
Merge pull request #623 from lenguyenthanh/optimize-attacks-initializ…
Browse files Browse the repository at this point in the history
…e-with-inlines

Use static annotation to optimize Bitboard Magic and Attacks
  • Loading branch information
lenguyenthanh authored Feb 17, 2025
2 parents 9ff7897 + a185b33 commit ffecc87
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 24 deletions.
17 changes: 5 additions & 12 deletions bench/src/main/scala/benchmarks/PerftBench.scala
Original file line number Diff line number Diff line change
Expand Up @@ -82,16 +82,9 @@ class PerftBench:
perfts.take(games).map(_.withLimit(nodes))

private def bench(perfts: List[Perft], variant: Variant)(bh: Blackhole) =
val x = perfts.map:
var i = 0
while i < perfts.size do
val game = perfts(i)
Blackhole.consumeCPU(Work)
_.calculate(variant)
bh.consume(x)
x

extension (perft: Perft)
def bench(variant: Variant): List[Result] =
var situation = Fen.read(variant, perft.epd).get
perft.cases.map: c =>
import Perft.*
Blackhole.consumeCPU(Work)
Result(c.depth, situation.perft(c.depth), c.result)
bh.consume(game.calculate(variant))
i += 1
2 changes: 1 addition & 1 deletion core/src/main/scala/Square.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import scala.annotation.targetName
opaque type Square = Int
object Square:
extension (s: Square)
def value: Int = s
inline def value: Int = s

inline def down: Option[Square] = Square.at(file.value, rank.value - 1)
inline def left: Option[Square] = Square.at(file.value - 1, rank.value)
Expand Down
39 changes: 29 additions & 10 deletions core/src/main/scala/bitboard/Attacks.scala
Original file line number Diff line number Diff line change
@@ -1,26 +1,45 @@
package chess
package bitboard

import scala.annotation.static

class Attacks
object Attacks:
@static
private val all = -1L

private[bitboard] val RANKS = Array.fill(8)(0L)
private[bitboard] val FILES = Array.fill(8)(0L)
@static
private[bitboard] val RANKS = Array.fill(8)(0L)
@static
private[bitboard] val FILES = Array.fill(8)(0L)
@static
private[bitboard] val BETWEEN = Array.ofDim[Long](64, 64)
private[bitboard] val RAYS = Array.ofDim[Long](64, 64)
@static
private[bitboard] val RAYS = Array.ofDim[Long](64, 64)

// Large overlapping attack table indexed using magic multiplication.
private[bitboard] val ATTACKS = Array.fill(88772)(0L)
private[bitboard] val KNIGHT_ATTACKS = Array.fill(64)(0L)
private[bitboard] val KING_ATTACKS = Array.fill(64)(0L)
@static
private[bitboard] val ATTACKS = Array.fill(88772)(0L)
@static
private[bitboard] val KNIGHT_ATTACKS = Array.fill(64)(0L)
@static
private[bitboard] val KING_ATTACKS = Array.fill(64)(0L)
@static
private[bitboard] val WHITE_PAWN_ATTACKS = Array.fill(64)(0L)
@static
private[bitboard] val BLACK_PAWN_ATTACKS = Array.fill(64)(0L)

private val KNIGHT_DELTAS = Array[Int](17, 15, 10, 6, -17, -15, -10, -6)
private val BISHOP_DELTAS = Array[Int](7, -7, 9, -9)
private val ROOK_DELTAS = Array[Int](1, -1, 8, -8)
private val KING_DELTAS = Array[Int](1, 7, 8, 9, -1, -7, -8, -9)
@static
private val KNIGHT_DELTAS = Array[Int](17, 15, 10, 6, -17, -15, -10, -6)
@static
private val BISHOP_DELTAS = Array[Int](7, -7, 9, -9)
@static
private val ROOK_DELTAS = Array[Int](1, -1, 8, -8)
@static
private val KING_DELTAS = Array[Int](1, 7, 8, 9, -1, -7, -8, -9)
@static
private val WHITE_PAWN_DELTAS = Array[Int](7, 9)
@static
private val BLACK_PAWN_DELTAS = Array[Int](-7, -9)

/** Slow attack set generation. Used only to bootstrap the attack tables.
Expand Down
6 changes: 5 additions & 1 deletion core/src/main/scala/bitboard/Magic.scala
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package chess
package bitboard

case class Magic(mask: Long, factor: Long, offset: Int):
import scala.annotation.static

class Magic(val mask: Long, val factor: Long, val offset: Int):
def bitshopIndex(occupied: Long): Int = (factor * (occupied & mask) >>> (64 - 9)).toInt + offset
def rookIndex(occupied: Long): Int = (factor * (occupied & mask) >>> (64 - 12)).toInt + offset

object Magic:
@static
private[bitboard] val ROOK = Array[Magic](
Magic(0x000101010101017eL, 0x00280077ffebfffeL, 26304),
Magic(0x000202020202027cL, 0x2004010201097fffL, 35520),
Expand Down Expand Up @@ -73,6 +76,7 @@ object Magic:
Magic(0x7e80808080808000L, 0x0001ffff9dffa333L, 14826)
)

@static
private[bitboard] val BISHOP = Array[Magic](
Magic(0x0040201008040200L, 0x007fbfbfbfbfbfffL, 5378),
Magic(0x0000402010080400L, 0x0000a060401007fcL, 4093),
Expand Down

0 comments on commit ffecc87

Please sign in to comment.