-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathbenchmark.go
140 lines (109 loc) · 2.72 KB
/
benchmark.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
package main
import (
"time"
"github.com/0hq/chess"
)
// measure how long minimax_plain takes run
// returns time in seconds
func benchmark(ply int, engine Engine, pos *chess.Position) float64 {
Reset_Global_Counters()
out("BEGIN BENCHMARKING -", engine.Name())
out("Ply:", ply)
out("Starting at time", time.Now())
start := time.Now()
move, eval := engine.Run_Engine(pos)
elapsed := time.Since(start)
out("Complete at time", time.Now())
out("Best move:", move)
out("Evaluation:", eval)
out("Elapsed time:", elapsed.Seconds(), "seconds")
out("Nodes explored:", explored)
out("END BENCHMARKING -")
return elapsed.Seconds()
}
func benchmark_range(plymin int, plymax int, engine Engine, pos *chess.Position) {
for i := plymin; i <= plymax; i++ {
benchmark(i, engine, pos)
}
}
func benchmark_engines(engines []Engine, pos *chess.Position) {
for _, engine := range engines {
benchmark_range(2, 4, engine, pos)
}
}
/*
Move ordering and generation benchmarks.
*/
/*
Perft Test
Benchmarks move generation and board update.
*/
var engine_perft EngineClass = EngineClass{
name: "Perft Test",
features: EngineFeatures{
plain: false,
parallel: false,
alphabeta: false,
iterative_deepening: false,
mtdf: false,
},
}
type type_benchmark_perft EngineClass
func (e *type_benchmark_perft) Run_Engine(pos *chess.Position, cfg EngineConfig) (best *chess.Move, eval int) {
count := perft(cfg.ply, pos)
explored = count
out("Perft nodes searched", count)
return nil, count
}
func perft(ply int, pos *chess.Position) int {
if ply == 0 {
return 1
}
moves := pos.ValidMoves()
count := 0
for _, move := range moves {
count += perft(ply-1, pos.Update(move))
}
return count
}
/*
Perft PLL Test
Runs in parallel.
Benchmarks move generation and board update.
*/
// define new engine
var engine_perft_pll EngineClass = EngineClass{
name: "Parallel Perft Test",
features: EngineFeatures{
plain: false,
parallel: true,
alphabeta: false,
iterative_deepening: false,
mtdf: false,
},
}
type type_benchmark_perft_pll EngineClass
func (e *type_benchmark_perft_pll) Run_Engine(pos *chess.Position, cfg EngineConfig) (best *chess.Move, eval int) {
count_channel := make(chan int, 1)
go perft_parallel(cfg.ply, pos, count_channel)
count := <-count_channel
explored = count
out("Perft nodes searched", count)
return nil, count
}
func perft_parallel(ply int, pos *chess.Position, count_channel chan int) int {
if ply == 0 {
return 1
}
moves := pos.ValidMoves()
length := len(moves)
count_channel_local := make(chan int, length)
for _, move := range moves {
go perft_parallel(ply-1, pos.Update(move), count_channel_local)
}
count := 0
for i := 0; i < length; i++ {
count += <-count_channel_local
}
return count
}