UCI Chess Engine written in C
- C 91.3%
- Shell 6.3%
- C++ 1.3%
- Makefile 1.1%
Bench: 2811728
No functional changes
The SIMD dispatch in accumulator.h and evaluate.c guards the NEON path on
__ARM_NEON__, with trailing underscores. Apple's clang defines that, but on
Linux aarch64 neither GCC nor Clang does -- both define __ARM_NEON. Measured
on Graviton, Ubuntu 24.04:
gcc 13.3.0 __ARM_NEON: 1 __ARM_NEON__: 0
clang 18.1.3 __ARM_NEON: 1 __ARM_NEON__: 0
So every Linux ARM build silently falls through to the scalar #else in
accumulator.h (UNROLL 16, plain acc_t) with no error and no warning. Nothing
in the makefile catches it either: ARM64 auto-detection tests `uname -m`
against arm64, but Linux reports aarch64, so ARCH stays native and
-march=native compiles the scalar path.
Both spellings are now accepted, so Apple Silicon is unaffected and Linux
aarch64 gets the NEON path it already had code for.
Measured, one hour on AWS spot, single-threaded bench:
scalar NEON speedup
Graviton 2 m6g 372,463 666,918 1.79x
Graviton 4 c8g 688,474 1,425,825 2.07x
bench reports 2,811,728 nodes on x86-64 AVX-512, ARM scalar and ARM NEON
alike. Bench is a fixed-depth search, so an identical node count means the
search tree and therefore every evaluation matched -- the NEON path is
numerically correct, not merely faster.
At AWS spot prices this moves a Graviton 4 host from 37% worse value than a
Zen 4 host to 14% better, measured as aggregate nodes/sec per dollar-hour
with every core busy.
Claude-Session: https://claude.ai/code/session_01ARJC6rsP7wt21NLnY7yixS
|
||
|---|---|---|
| .github/workflows | ||
| docs/plans | ||
| resources | ||
| src | ||
| tests | ||
| .clang-format | ||
| .gitignore | ||
| .gitmodules | ||
| LICENSE | ||
| README.md | ||
Berserk Chess Engine
A UCI chess engine written in C. Feel free to challenge me on Lichess!
Strength
Rating Lists + Elo
Many websites use an Elo rating system to present relative skill amongst engines. Below is a list of many chess engine lists throughout the web (variance in Elo is due to different conditions for each list)
- CCRL 40/15 - 3514 4CPU, 3480 1CPU
- CCRL 40/2 - 3667 1CPU
- IpMan Chess - 3547 1CPU
- CEGT - 3598 1CPU
- SPCC - 3733 1CPU
FGRL - 3518 1CPU- List no longer maintained
Tournaments/Events with Berserk
Functional Details
Board Representation and Move Generation
Search
- Negamax
- Quiescence
- Iterative Deepening
- Transposition Table
- Aspiration Windows
- Internal Iterative Reductions
- Reverse Futility Pruning
- Razoring
- Null Move Pruning
- ProbCut
- FutilityPruning
- History Pruning
- SEE
- Static Exchange Evaluation Pruning
- LMR
- Killer Heuristic
- Countermove Heuristic
- Extensions
Evaluation
- NNUE
- Horizontally Mirrored 16 Buckets
- 2x(12288 -> 512) -> 1
- Berserk FenGen
- Grapheus
Koivisto's CUDA Trainer- This has been deprecated in favor of an even newer trainer written by Luecx, Grapheus.
Berserk Trainer- This has been deprecated in favor of Koivisto's trainer, but trained all networks through Berserk 8.5.1+
Building
git clone https://github.com/jhonnold/berserk && \
cd berserk/src && \
make pgo CC=clang && \
./berserk
Credit
This engine could not be written without some influence and they are...
Engine Influences
Additional Resources
- Grapheus
- Koivisto's CUDA Trainer
- OpenBench
- TalkChess Forum
- CCRL
- JCER
- Cute Chess
- Arena
- CPW
- Lars in Grahams Broadcast rooms