並列探索できた!

ルートでの分割はやめて任意の深さで、残深さと残手数があるときに分割して並列化するようにしました
自己対戦で勝ち越すので大丈夫のようです。


始めはスレッドループで無限ループでSleep(1)で回すとかやってましたが、ちゃんとイベントをWaitForSingleObjectで待つようにしてやると
効率が良くなりました。



ルートでの分割の可否については、
たとえば、評価関数が優れている場合、深く読むほどにルートの最善手が変化する確率は下がりますので、
ある程度深く読むと、ルートは1手目の探索に大多数の時間が必要で、カットノードはヌルウィンドウ探索で再探索される割合が減ると思います
ということは、ルートで分割すると、そもそも時間がかかるはずの最善手の探索効率を良くしないので効率が悪いはずです。
ただ、思考時間が1秒とかの場合は、ルートでPVが変化する可能性も高いので、ルートで分割しても悪くないと思います


まだ4並列では試してないのでやってみましょう



いわゆるCrafty型の自分が親にも子にもなるタイプではなく、masterとslave型の並列探索(だってこっちのほうが作るの楽だもん)


作った関数は

extern void CreateSMP();
extern void StartSMP(int tid);
extern void WaitForSMP();
extern void ThreadStop();
extern int search_smp(int tid,uchar SorE,int alpha,int beta,int depth, double depthMax, int doNull, Te t[],int i,int tp );
extern int CopyToSMP(Shogi& tree,int cpuno);

手順としては
CreateSMPでスレッドを起動
残探索深さと残手数がそれなりにある場合に、
CopyToSMPで盤面などの情報をスレッドにコピー
StartSMPで起動している探索スレッドに探索開始を指示
WaitForSMPでMasterはslaveの探索が終わるのを待つ
slaveの探索がすべて終われば、masterは一番の最善手を決定。元の処理に復帰


slave側は、StartSMPから探索開始指示イベントが来ると、search_smpを呼び出す。
もし探索中にベータカットが起きた場合はThreadStopで他のスレッドをすべて止める
普通に探索が終わった場合は、スレッドループに戻る