예제 #1
0
  // 協力詰め探索の反復深化のループ
  void id_loop(Position& pos, int thread_id, int thread_num)
  {
    pos.set_nodes_searched(0);
    auto start_time = now();

    // 協力詰めの反復深化は2手ずつ深くして良い。
    // lazy SMPっぽい並列化をする。
    for (uint32_t depth = 1 + thread_id * 2; depth < MAX_PLY; depth += 2 * thread_num)
    {
      // 置換表のgenerationをインクリメントするのはmain threadだけ。
      if (thread_id == 0)
        TT.new_search();

      int no_mate_depth;
      id_depth_thread = depth;
      search(pos, depth, no_mate_depth);

      if (Signals.stop || mate_found)
        break;

      // 定期的にdepth、nodes、npsを出力する。
      auto end_time = now();
      auto node_searched = Threads.nodes_searched(); // 全スレッドでの探索合計
      sync_cout << "info  depth " << depth
        << " nodes " << node_searched
        << " nps " << (node_searched * 1000 / ((int64_t)(end_time - start_time + 1)))
        << " hashfull " << TT.hashfull()
        << sync_endl;

      // 最大探索深さに到達する前に王手が続かなくなっていたなら終了
      if (no_mate_depth == MAX_PLY)
      {
        sync_cout << "checkmate nomate" << sync_endl;
        break;
      }

      // depth手では詰まないことが証明できたのでsearch_depthを書き換える。
      // 他のスレッドが書き換える可能性もあるので値が大きいときのみ。
      while (true)
      {
        auto sd = search_depth.load();
        if (depth > sd)
        {
          if (search_depth.compare_exchange_weak(sd, depth))
            break;
        } else break; // 下回っているので書き込む価値はない。
      }
    }
  }