-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy paththread.cc
More file actions
102 lines (81 loc) · 2.69 KB
/
thread.cc
File metadata and controls
102 lines (81 loc) · 2.69 KB
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
// Copyright (C) 2016 Tetsui Ohkubo.
#include "./thread.h"
#include <gflags/gflags.h>
#include <cstdlib>
#include <iostream>
DEFINE_int32(num_threads, 2, "Number of threads to be used for Lazy SMP.");
void SearchThread::StartSearch(const Position& position, Timer *timer) {
{
// Check search is not running and thread is running.
std::lock_guard<std::mutex> lock(mutex_);
if (is_searching_ || is_quit_) {
std::cerr << "Search is already running or already quit" << std::endl;
exit(EXIT_FAILURE);
}
}
root_position_ = &position;
timer_ = timer;
// Set searching and notify condition variable
{
std::lock_guard<std::mutex> lock(mutex_);
is_searching_ = true;
}
condition_.notify_all();
}
void SearchThread::Wait() {
std::unique_lock<std::mutex> lock(mutex_);
condition_.wait(lock, [=]{ return !is_searching_; });
}
void SearchThread::Loop() {
while (!is_quit_) {
{
std::unique_lock<std::mutex> lock(mutex_);
// This may help you understand that lambda:
// https://cpplover.blogspot.jp/2010/06/lambda_15.html
condition_.wait(lock, [=]{ return is_searching_ || is_quit_; });
}
if (is_searching_ && !is_quit_) {
// Perform actual search.
searcher_->DoSearchBestMove(
*root_position_, thread_index_, num_threads_, timer_,
&best_move_, &best_score_, &completed_depth_);
}
{
std::lock_guard<std::mutex> lock(mutex_);
is_searching_ = false;
}
condition_.notify_all();
}
}
ThreadedSearcher::ThreadedSearcher() : threads_(FLAGS_num_threads) {
for (int i = 0; i < threads_.size(); ++i) {
threads_[i].set_searcher(this);
threads_[i].set_thread_index(i);
threads_[i].set_num_threads(threads_.size());
}
}
Move ThreadedSearcher::SearchBestMove(const Position& position, Timer *timer) {
for (SearchThread& thread : threads_) {
thread.StartSearch(position, timer);
}
for (SearchThread& thread : threads_) {
// Threads are expected to stop within the time limit using the timer.
thread.Wait();
}
// Select the thread with the best search depth and the best score.
int best_index = 0;
for (int i = 0; i < threads_.size(); ++i) {
/*
std::cerr << "thread " << i << ": depth " << threads_[i].completed_depth()
<< " score: " << threads_[i].best_score() << std::endl;
*/
if (threads_[i].completed_depth() > threads_[best_index].completed_depth()
||
(threads_[i].completed_depth() == threads_[best_index].completed_depth()
&& threads_[i].best_score() >= threads_[best_index].best_score())) {
best_index = i;
}
}
// Return the best move of that thread.
return threads_[best_index].best_move();
}