alphaBeta2Parallel.h
Go to the documentation of this file.
00001 /* alphaBeta2Parallel.h
00002  */
00003 #ifndef _ALPHABETA2PARALLEL_H
00004 #define _ALPHABETA2PARALLEL_H
00005 
00006 #ifdef OSL_SMP
00007 
00008 #include "osl/search/alphaBeta2.h"
00009 #include "osl/misc/atomicCounter.h"
00010 #include "osl/stl/vector.h"
00011 #include <boost/shared_ptr.hpp>
00012 #include <boost/thread/thread.hpp>
00013 #include <boost/thread/mutex.hpp>
00014 #include <boost/thread/condition.hpp>
00015 #include <boost/ptr_container/ptr_vector.hpp>
00016 
00017 #define SPLIT_STAT
00018 // #define OSL_SMP_NO_SPLIT_ROOT
00019 
00020 namespace osl
00021 {
00022   namespace search
00023   {
00024     // block_id: -1 illegal, 0 not used (master tree), 1- parallel search
00025     struct AlphaBeta2ParallelCommon : boost::noncopyable
00026     {
00027       struct TreeInfoCommon
00028       {
00029         int thread_id;
00030         volatile int nprocs;
00031         MoveLogProb best_move;
00032         AlphaBeta2Window window;
00033         int value;
00034         size_t nodes_searched;
00035         bool is_root, in_pv;
00036         Player turn;
00037       };
00038       struct TreeInfo : public TreeInfoCommon
00039       {
00040         CArray<volatile int, OslConfig::MaxThreads> siblings;
00041         volatile int parent;
00042         MoveLogProbVector moves;
00043         volatile int move_index, search_value;
00044         int alpha_update, last_alpha_update;
00045         volatile bool used;
00046         LightMutex lock;
00047 
00048         TreeInfo() : used(0)
00049         {
00050           siblings.fill(0);
00051         }
00052         void set(const TreeInfo& parent, int max_threads)
00053         {
00054           TreeInfoCommon::operator=(parent);
00055           used = true;
00056           for (int i=0; i<max_threads; i++)
00057             siblings[i] = 0;
00058           search_value = 0;  
00059         }
00060       };
00061       struct LivingThreadLock;
00062       typedef SearchState2::checkmate_t checkmate_t;
00063       static const int MaxBlocksPerCpu = 16;
00064       static const int MaxBlocks = OslConfig::MaxThreads*MaxBlocksPerCpu+1;
00065       CArray<volatile int, OslConfig::MaxThreads> job;
00066       CArray<checkmate_t*, OslConfig::MaxThreads> checkmate;
00067 
00068       CArray<TreeInfo,MaxBlocks> info;
00070       CArray<volatile int,OslConfig::MaxThreads> waiting;
00071       CArray<boost::thread*,OslConfig::MaxThreads> threads;
00072       boost::mutex lock_smp;
00073       boost::condition condition_smp;
00074       volatile int smp_idle;
00075       volatile bool quit;
00076       unsigned int parallel_splits;
00077       unsigned int max_split_depth, descendant_reject, descendant_test;
00078 
00079       boost::mutex living_threads_lock;
00080       boost::condition living_threads_condition;
00081       volatile int living_threads;
00082 
00083       int max_threads, max_thread_group;
00084       int split_min_limit;
00085 
00086       int my_id;
00087       AtomicCounter parallel_abort;
00088       AtomicCounter cancelled_splits;
00089       bool started;
00090 
00091       AlphaBeta2ParallelCommon();
00092       ~AlphaBeta2ParallelCommon();
00093       static checkmate_t*& checkmateSearcher(SearchState2& state) { return state.checkmate_searcher; }
00094 
00095       void waitAll();
00096       bool isDescendant(int elder, int younger);
00097 
00098       struct SplitFailed {};
00099     };
00100     template <class EvalT>
00101     struct AlphaBeta2Parallel : public AlphaBeta2ParallelCommon
00102     {
00103       struct Worker
00104       {
00105         AlphaBeta2Parallel *shared;
00106         int thread_id;
00107         Worker(int tid, AlphaBeta2Parallel *shared);
00108         void operator()();
00109       };
00110 
00111       typedef AlphaBeta2Tree<EvalT> tree_t;
00112       CArray<tree_t*,MaxBlocks> tree;
00113       tree_t *master;
00114 
00115       explicit AlphaBeta2Parallel(tree_t *master);
00116       ~AlphaBeta2Parallel();
00117       void threadStart();
00118 
00119       void testStop();
00120 
00121       void search(int tree_id);
00122       void threadWait(int thread_id, int waiting);
00124       bool split(tree_t *tree, int tree_id, int thread_id, int max_split);
00125       void stopThread(int tree_id);
00126       void copyToParent(int parent, int child);
00128       int copyToChild(int parent, int thread_id);
00129 
00130       int treeId(tree_t *tree);
00131       int parentID(int tree_id) { return info[tree_id].parent; }
00132       TreeInfo* parent(int tree_id) { return &info[parentID(tree_id)]; }
00133       const std::pair<MoveLogProb,size_t> nextMove(int tree_id);
00134       size_t checkmateCount() const;
00135       size_t mainCheckmateCount() const;
00136     };
00137   }
00138 }
00139 
00140 #endif /* OSL_SMP */
00141 
00142 #endif /* _ALPHABETA2PARALLEL_H */
00143 // ;;; Local Variables:
00144 // ;;; mode:c++
00145 // ;;; c-basic-offset:2
00146 // ;;; End:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines