Crafty CHESSの並列探索のコードを読む
一応並列化を取り組んでみてから読むと格段に判りやすいですね。
コードを読んで流れをメモっておきます。
言葉で説明すると、予めプロセッサ(コア)の数だけスレッドを起動しておいて、
アイドリングさせておく。
反復深化で、local[0]をCPU#0に投下する。
アイドリングしていたCPU#0スレッドがsearchSMPを呼んでsearch()を使ってPVS探索する。
サーチ中に分割するあたりは、まだ読み切れてないので、
帰宅してから読みます。
Iterate() { NumaStartThread() { _beginthreadex(ThreadInit); WaitForAllThreadInit(); } for( iterataion ) while(1) { thread[0]=local[0]; v=searchRoot(); if(v>beta) .... if(v<=alpha) ... } // read_clock } } STDCALL ThreadInit() { threadMalloc(); threadWait(); } ThreadWait() { while(1) { if(share->thread==waiting ) return(0); value = searchSMP(alpha,beta) CopyFromSMP(thread->parent; } } searchSMP(alpha,beta,depth) { while(1) { make_move(NEXT) value=search(-alpha-1,-alpha); if(value>alpha && value<beta) value=search(-beta,-alpha); if(value>=alpha) { alpha=value; if(value>=beta) { unmake(); for() threadStop(parent); break; } } unmake(); } return(alpha); } search_root(alpha,beta,depth) { firstmove=1; while(NextRootMove) { make_move() if(firstMove) { value=search(-beta,-alpha); firstmove=0; } else { value=search(-alpha-1,-alpha); if(value>alpha && value<beta) value=search(-beta,-alpha); if(value>=alpha) { alpha=value; if(value>=beta) { //history regist unmake(); return(alpha); } } } unmake(); } return(alpha); }