bool team_work(void worker(void)) { // Current state is other threads are at wait_for_job_. // This master thread (thread zero) has not completed wait_for_job_ bool ok = sequential_execution_; ok &= thread_number() == 0; ok &= wait_for_work_ != CPPAD_NULL; ok &= wait_for_job_ != CPPAD_NULL; // set global version of this work routine worker_ = worker; // set the new job that other threads are waiting for thread_job_ = work_enum; // Enter parallel exectuion when master thread calls wait_for_job_ if( num_threads_ > 1 ) sequential_execution_ = false; wait_for_job_->wait(); // Now do the work in this thread and then wait // until all threads have completed wait_for_work_ worker(); wait_for_work_->wait(); // Current state is other threads are at wait_for_job_. // This master thread (thread zero) has not completed wait_for_job_ sequential_execution_ = true; size_t thread_num; for(thread_num = 0; thread_num < num_threads_; thread_num++) ok &= thread_all_[thread_num].ok; return ok; }
static int history_prob(int move, const board_t * board) { int value; int index; ASSERT(move_is_ok(move)); ASSERT(board!=NULL); ASSERT(!MOVE_IS_TACTICAL(move,board)); index = history_index(move,board); #if DEBUG if (thread_number() == 1) { ASSERT(HistHit[index]<=HistTot[index]); ASSERT(HistTot[index]<HistoryMax); } #endif value = (HistHit[index] * 16384) / HistTot[index]; if (value > 16384) value = 16384; // HACK: Thread related ASSERT(value>=0&&value<=16384); return value; }
static int quiet_move_value(int move, const board_t * board) { int value; int index; ASSERT(move_is_ok(move)); ASSERT(board!=NULL); ASSERT(!MOVE_IS_TACTICAL(move,board)); index = history_index(move,board); value = History[index]; #if DEBUG if (thread_number() > 1) { ASSERT(value<=HistoryValue+8192&&value>=-HistoryValue-8192); } else { ASSERT(value<=HistoryValue&&value>=-HistoryValue); } #endif if (UseMoveEval) { if (value > HistoryScore) value += HistoryEvalMax; value += HISTORY_EVAL(HistEval[index]); } value /= HeightFull; ASSERT(value>=BadScore+100&&value<KillerScore-4); return value; }
bool team_destroy(void) { // Current state is other threads are at wait_for_job_. // This master thread (thread zero) has not completed wait_for_job_ bool ok = sequential_execution_; ok &= thread_number() == 0; ok &= wait_for_work_ != CPPAD_NULL; ok &= wait_for_job_ != CPPAD_NULL; // set the new job that other threads are waiting for thread_job_ = join_enum; // enter parallel exectuion soon as master thread completes wait_for_job_ if( num_threads_ > 1 ) sequential_execution_ = false; wait_for_job_->wait(); // now wait for the other threads to be destroyed size_t thread_num; ok &= thread_all_[0].bthread == CPPAD_NULL; for(thread_num = 1; thread_num < num_threads_; thread_num++) { thread_all_[thread_num].bthread->join(); delete thread_all_[thread_num].bthread; thread_all_[thread_num].bthread = CPPAD_NULL; } // now we are down to just the master thread (thread zero) sequential_execution_ = true; // destroy wait_for_work_ delete wait_for_work_; wait_for_work_ = CPPAD_NULL; // destroy wait_for_job_ delete wait_for_job_; wait_for_job_ = CPPAD_NULL; // check ok before changing num_threads_ for(thread_num = 0; thread_num < num_threads_; thread_num++) ok &= thread_all_[thread_num].ok; // now inform CppAD that there is only one thread num_threads_ = 1; thread_alloc::parallel_setup(num_threads_, CPPAD_NULL, CPPAD_NULL); thread_alloc::hold_memory(false); CppAD::parallel_ad<double>(); return ok; }
void bad_move(int move, const board_t * board, int depth) { int index; int i; ASSERT(move_is_ok(move)); ASSERT(board!=NULL); ASSERT(depth_is_ok(depth)); if (MOVE_IS_TACTICAL(move,board)) return; // history index = history_index(move,board); History[index] -= HISTORY_INC(depth); if (History[index] < -HistoryValue) { for (i = 0; i < HistorySize; i++) { if (History[i] >= 0) { History[i] = (History[i] + 1) / 2; } else { History[i] = (History[i] - 1) / 2; } } } HistTot[index]++; if (HistTot[index] >= HistoryMax) { HistHit[index] = (HistHit[index] + 1) / 2; HistTot[index] = (HistTot[index] + 1) / 2; } #if DEBUG if (thread_number() == 1) { ASSERT(History[index]<=HistoryValue&&History[index]>=-HistoryValue); ASSERT(HistHit[index]<=HistTot[index]); ASSERT(HistTot[index]<HistoryMax); } else { ASSERT(History[index]<=HistoryValue+8192&&History[index]>=-HistoryValue-8192); } #endif }
void good_move(int move, const board_t * board, int depth, int height, int thread, bool cut) { int index; int i; ASSERT(move_is_ok(move)); ASSERT(board!=NULL); ASSERT(depth_is_ok(depth)); ASSERT(height_is_ok(height)); ASSERT(thread_is_ok(thread)); ASSERT(cut==true||cut==false); if (MOVE_IS_TACTICAL(move,board)) return; // killer if (Killer[thread][height][0] != move) { Killer[thread][height][1] = Killer[thread][height][0]; Killer[thread][height][0] = move; } ASSERT(Killer[thread][height][0]==move); ASSERT(Killer[thread][height][1]!=move); // history index = history_index(move,board); History[index] += HISTORY_INC(depth); if (History[index] > HistoryValue) { for (i = 0; i < HistorySize; i++) { if (History[i] >= 0) { History[i] = (History[i] + 1) / 2; } else { History[i] = (History[i] - 1) / 2; } } } if (cut) { HistHit[index]++; HistTot[index]++; if (HistTot[index] >= HistoryMax) { HistHit[index] = (HistHit[index] + 1) / 2; HistTot[index] = (HistTot[index] + 1) / 2; } #if DEBUG if (thread_number() == 1) { ASSERT(HistHit[index]<=HistTot[index]); ASSERT(HistTot[index]<HistoryMax); } #endif } #if DEBUG if (thread_number() > 1) { ASSERT(History[index]<=HistoryValue+8192&&History[index]>=-HistoryValue-8192); } else { ASSERT(History[index]<=HistoryValue&&History[index]>=-HistoryValue); } #endif }