All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
alphaBeta2Parallel.h
Go to the documentation of this file.
1 /* alphaBeta2Parallel.h
2  */
3 #ifndef _ALPHABETA2PARALLEL_H
4 #define _ALPHABETA2PARALLEL_H
5 
6 #ifdef OSL_SMP
7 
10 #include "osl/stl/vector.h"
11 #include <boost/shared_ptr.hpp>
12 #include <boost/thread/thread.hpp>
13 #include <boost/thread/mutex.hpp>
14 #include <boost/thread/condition.hpp>
15 #include <boost/ptr_container/ptr_vector.hpp>
16 
17 #define SPLIT_STAT
18 // #define OSL_SMP_NO_SPLIT_ROOT
19 
20 namespace osl
21 {
22  namespace search
23  {
24  // block_id: -1 illegal, 0 not used (master tree), 1- parallel search
25  struct AlphaBeta2ParallelCommon : boost::noncopyable
26  {
27  struct TreeInfoCommon
28  {
29  int thread_id;
30  volatile int nprocs;
31  MoveLogProb best_move;
32  AlphaBeta2Window window;
33  int value;
34  size_t nodes_searched;
35  bool is_root, in_pv;
36  Player turn;
37  };
38  struct TreeInfo : public TreeInfoCommon
39  {
40  CArray<volatile int, OslConfig::MaxThreads> siblings;
41  volatile int parent;
42  MoveLogProbVector moves;
43  volatile int move_index, search_value;
44  int alpha_update, last_alpha_update;
45  volatile bool used;
46  LightMutex lock;
47 
48  TreeInfo() : used(0)
49  {
50  siblings.fill(0);
51  }
52  void set(const TreeInfo& parent, int max_threads)
53  {
54  TreeInfoCommon::operator=(parent);
55  used = true;
56  for (int i=0; i<max_threads; i++)
57  siblings[i] = 0;
58  search_value = 0;
59  }
60  };
61  struct LivingThreadLock;
63  static const int MaxBlocksPerCpu = 16;
64  static const int MaxBlocks = OslConfig::MaxThreads*MaxBlocksPerCpu+1;
65  CArray<volatile int, OslConfig::MaxThreads> job;
66  CArray<checkmate_t*, OslConfig::MaxThreads> checkmate;
67 
68  CArray<TreeInfo,MaxBlocks> info;
70  CArray<volatile int,OslConfig::MaxThreads> waiting;
71  CArray<boost::thread*,OslConfig::MaxThreads> threads;
72  boost::mutex lock_smp;
73  boost::condition condition_smp;
74  volatile int smp_idle;
75  volatile bool quit;
76  unsigned int parallel_splits;
77  unsigned int max_split_depth, descendant_reject, descendant_test;
78 
79  boost::mutex living_threads_lock;
80  boost::condition living_threads_condition;
81  volatile int living_threads;
82 
83  int max_threads, max_thread_group;
84  int split_min_limit;
85 
86  int my_id;
87  AtomicCounter parallel_abort;
88  AtomicCounter cancelled_splits;
89  bool started;
90 
91  AlphaBeta2ParallelCommon();
92  ~AlphaBeta2ParallelCommon();
93  static checkmate_t*& checkmateSearcher(SearchState2& state) { return state.checkmate_searcher; }
94 
95  void waitAll();
96  bool isDescendant(int elder, int younger);
97 
98  struct SplitFailed {};
99  };
100  template <class EvalT>
101  struct AlphaBeta2Parallel : public AlphaBeta2ParallelCommon
102  {
103  struct Worker
104  {
105  AlphaBeta2Parallel *shared;
106  int thread_id;
107  Worker(int tid, AlphaBeta2Parallel *shared);
108  void operator()();
109  };
110 
111  typedef AlphaBeta2Tree<EvalT> tree_t;
112  CArray<tree_t*,MaxBlocks> tree;
113  tree_t *master;
114 
115  explicit AlphaBeta2Parallel(tree_t *master);
116  ~AlphaBeta2Parallel();
117  void threadStart();
118 
119  void testStop();
120 
121  void search(int tree_id);
122  void threadWait(int thread_id, int waiting);
124  bool split(tree_t *tree, int tree_id, int thread_id, int max_split);
125  void stopThread(int tree_id);
126  void copyToParent(int parent, int child);
128  int copyToChild(int parent, int thread_id);
129 
130  int treeId(tree_t *tree);
131  int parentID(int tree_id) { return info[tree_id].parent; }
132  TreeInfo* parent(int tree_id) { return &info[parentID(tree_id)]; }
133  const std::pair<MoveLogProb,size_t> nextMove(int tree_id);
134  size_t checkmateCount() const;
135  size_t mainCheckmateCount() const;
136  };
137  }
138 }
139 
140 #endif /* OSL_SMP */
141 
142 #endif /* _ALPHABETA2PARALLEL_H */
143 // ;;; Local Variables:
144 // ;;; mode:c++
145 // ;;; c-basic-offset:2
146 // ;;; End: