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);
}