thanks for yor atention.
singe thread goes fine... an probably alpha-beta goes fine too.
Excuse the spanglis
hijo=son
padre=father
threads_disponibles=threads_availables
Code: Select all
#include "StdAfx.h"
#include "windows.h"
#include "process.h"
#include "posicion.h"
#include "bitboards.h"
#include "global.h"
#include "mt.h"
#include "Winbase.h"
using namespace std;
//-------------------------------------------------------------------
//INICIO RESULTADOS
//-------------------------------------------------------------------
class result
{
public:
int n;
int eval[256];
int move[256];
result (void);
~result (void);
};
//-------------------------------------------------------------------
result::result(void)
{
n=0;
for (int i=0;i<256;i++) eval[i]=0;
for (int i=0;i<256;i++) move[i]=0;
}
//-------------------------------------------------------------------
result::~result(void)
{
}
//-------------------------------------------------------------------
class result *resultados;
//-------------------------------------------------------------------
CRITICAL_SECTION CR_result;
CRITICAL_SECTION CR_threads;
CRITICAL_SECTION CR_split;
CRITICAL_SECTION CR_print;
CRITICAL_SECTION CR_familia;
//-------------------------------------------------------------------
void add_result (int padre,int evl,int mov)
{
EnterCriticalSection (&CR_result);
int index=resultados[padre].n;
resultados[padre].n++;
resultados[padre].eval[index]=evl;
resultados[padre].move[index]=mov;
LeaveCriticalSection (&CR_result);
}
//-------------------------------------------------------------------
void get_result (int Id,int &x,int &y)
{
EnterCriticalSection (&CR_result);
resultados[Id].n--;
int index=resultados[Id].n;
x=resultados[Id].eval[index];
y=resultados[Id].move[index];
LeaveCriticalSection (&CR_result);
}
//-------------------------------------------------------------------
int th_resultados_disponibles (int Id)
{
EnterCriticalSection (&CR_result);
int x=resultados[Id].n;
LeaveCriticalSection (&CR_result);
return x;
}
//-------------------------------------------------------------------
//FIN RESULTADOS
//-------------------------------------------------------------------
int MAX_THREADS=0;
int threads_disponibles=0;
HANDLE *HT;
int MT_destino,MT_mov,MT_beta,MT_depth,MT_tipo;
//-------------------------------------------------------------------
//INIT THREAD
//-------------------------------------------------------------------
unsigned __stdcall Init_thread (void* arg)
{
int ID=*((int *) arg);
//Informa de la creación de las threads
cout<<"info iniciando thread "<<ID<<endl;
for(;;) //(Forever)
{
setjmp (GLOBAL_TH[ID].Jump); //El salto
ZMT[ID].stop =0; //Justo despues del salto
EnterCriticalSection (&CR_threads);
threads_disponibles++;
LeaveCriticalSection (&CR_threads);
ZMT[ID].usable=1;//usable
WaitForSingleObject(GLOBAL_TH[ID].evento,INFINITE);
EnterCriticalSection (&CR_threads);
threads_disponibles--;
int mov =GLOBAL_TH[ID].mov;
int beta =GLOBAL_TH[ID].beta;
int depth =GLOBAL_TH[ID].depth;
int tipo =GLOBAL_TH[ID].tipo;
int nmovs =GLOBAL_TH[ID].nmovs;
int padre =GLOBAL_TH[ID].padre;
int eval;
LeaveCriticalSection (&CR_threads);
eval=ZMT[ID].search_mt(mov,beta,depth,tipo,nmovs);
EnterCriticalSection (&CR_threads);
add_result (padre,eval,mov);
ZMT[padre].th_borra_hijo (ID);
LeaveCriticalSection (&CR_threads);
EnterCriticalSection (&CR_print);
cout<<".";
LeaveCriticalSection (&CR_print);
};
_endthreadex(0);
return 0;
};
//-------------------------------------------------------------------
//SEARCH MT
//-------------------------------------------------------------------
int posicion::search_mt (int movimiento,int beta,int depth,int tipo,int nmovs)
{
mueve(movimiento);
int ev;
int enjaque=0;
if ((turno==BLANCO)&&(jaqueb(lsb(rb)))) enjaque=1;
if ((turno==NEGRO) &&(jaquen(lsb(rn)))) enjaque=1;
int extension=0;
if (enjaque) extension=PLY;
int nueva_depth=depth-PLY+extension;
if ((enjaque==0)&&(depth>=(3*PLY))&&(nmovs>=4)&&(S->tipo_mov==MOV_MOVE)) nueva_depth=depth-2*PLY;//LMR
if (enjaque) ev=-alfabeta_chk (1-beta,nueva_depth,tipo^1);
else ev=-alfabeta (1-beta,nueva_depth,tipo^1);
if ((nueva_depth<(depth-PLY))&&(ev>=beta))
{
if (enjaque) ev=-alfabeta_chk (1-beta,depth-PLY,tipo^1);
else ev=-alfabeta (1-beta,depth-PLY,tipo^1);
}
return ev;
}
//-------------------------------------------------------------------
//SPLIT
//-------------------------------------------------------------------
int posicion::split (int mov,int beta,int depth,int tipo,int nmovs)
{
EnterCriticalSection (&CR_split);
//-------------------------------------------------------------------
//BUSCA THREAD EN ESPERA
//-------------------------------------------------------------------
for (int ID=1;ID<MAX_THREADS;ID++)
if (ZMT[ID].usable==1)
{
ZMT[ID].usable=0;
//-------------------------------------------------------------------
//COPIA
//-------------------------------------------------------------------
ZMT[ID].S=&ZMT[ID].pS[0];
ZMT[ID].turno =turno;
ZMT[ID].estado =estado;
ZMT[ID].np2 =np2;
ZMT[ID].pb =pb;
ZMT[ID].cb =cb;
ZMT[ID].ab =ab;
ZMT[ID].tb =tb;
ZMT[ID].db =db;
ZMT[ID].rb =rb;
ZMT[ID].pn =pn;
ZMT[ID].cn =cn;
ZMT[ID].an =an;
ZMT[ID].tn =tn;
ZMT[ID].dn =dn;
ZMT[ID].rn =rn;
ZMT[ID].hash_key =hash_key;
ZMT[ID].hash_key_p =hash_key_p;
ZMT[ID].mov100 =mov100;
//-------------------------------------------------------------------
//TRANSICION
//-------------------------------------------------------------------
GLOBAL_TH[ID].mov =mov;
GLOBAL_TH[ID].beta =beta;
GLOBAL_TH[ID].depth =depth;
GLOBAL_TH[ID].tipo =tipo;
GLOBAL_TH[ID].nmovs =nmovs;
//-------------------------------------------------------------------
//FAMILIA
//-------------------------------------------------------------------
GLOBAL_TH[ID].padre =Id;
hijo[n_hijos] =ID;
n_hijos++;
//-------------------------------------------------------------------
//ARRANQUE
//-------------------------------------------------------------------
//Arranca el multi thread
SetEvent(GLOBAL_TH[ID].evento);
//-------------------------------------------------------------------
LeaveCriticalSection (&CR_split);
return 1;
}
LeaveCriticalSection (&CR_split);
return 0;
}
//-------------------------------------------------------------------
//INICIA MULTITHREAD
//-------------------------------------------------------------------
void init_multithread (int max_threads)
{
//-------------------------------------------------------------------
//Critical section esto es de lo primero que hay que hacer
//-------------------------------------------------------------------
InitializeCriticalSection(&CR_threads);
InitializeCriticalSection(&CR_split);
InitializeCriticalSection(&CR_result);
InitializeCriticalSection(&CR_print);
InitializeCriticalSection(&CR_familia);
//-------------------------------------------------------------------
SYSTEM_INFO sys;
GetSystemInfo (&sys);
N_NUCLEOS=sys.dwNumberOfProcessors;
cout<<"info "<<N_NUCLEOS<<" processors"<<endl;
//-------------------------------------------------------------------
max_threads++;
MAX_THREADS=max_threads;
GLOBAL_TH =new struct multi_th [max_threads];
HT =new HANDLE [max_threads];
VMT =new int [max_threads];
ZMT =new class posicion [max_threads];
resultados =new class result [max_threads];
if (ZMT==NULL) cout<<"info insuficient memory"<<endl;
//-------------------------------------------------------------------
for (int i=0;i<max_threads;i++) ZMT[i].Id =i;
threads_disponibles =0;
for (int i=0;i<max_threads;i++) ZMT[i].stop =0;
for (int i=0;i<max_threads;i++) ZMT[i].n_hijos=0;
for (int i=0;i<max_threads;i++) ZMT[i].usable =0;
for (int i=0;i<max_threads;i++) GLOBAL_TH[i].evento=INVALID_HANDLE_VALUE;
for (int i=1;i<max_threads;i++) GLOBAL_TH[i].evento=CreateEvent(0,FALSE,FALSE,0);
//-------------------------------------------------------------------
unsigned threadID;
for (int i=1;i<max_threads;i++)
{
threadID;
HT[i]=(HANDLE) _beginthreadex (NULL,0,&Init_thread,&i,0,&threadID);
Sleep(10);//le damos un tiempo para iniciar todo
cout<<"info thread "<<i<<" iniciada Id="<<threadID<<endl;
}
//-------------------------------------------------------------------
cout<<"info "<<threads_disponibles<<" threads"<<endl;
}
//-------------------------------------------------------------------
//stop_thread
//-------------------------------------------------------------------
void posicion::stop_thread (void)
{
for (int i=0;i<n_hijos;i++) ZMT[hijo[i]].stop_thread ();
for (int i=0;i<256 ;i++) hijo[i]=0;
n_hijos=0;
clean_results ();
stop=1;
}
//-------------------------------------------------------------------
//clean results
//-------------------------------------------------------------------
void posicion::clean_results (void)
{
EnterCriticalSection (&CR_result);
resultados[Id].eval[resultados[Id].n]=0;
resultados[Id].move[resultados[Id].n]=0;
resultados[Id].n=0;
LeaveCriticalSection (&CR_result);
}
//-------------------------------------------------------------------
//stop_hijos
//-------------------------------------------------------------------
void posicion::stop_hijos (void)
{
int index;
for (int i=0;i<n_hijos;i++)
{
index=hijo[i];
ZMT[index].stop_thread ();
ZMT[index].clean_results ();
}
n_hijos=0;
}
//-------------------------------------------------------------------
//th_esperando_resultado
//-------------------------------------------------------------------
int posicion::th_esperando_resultado (void)
{
return n_hijos;
}
//-------------------------------------------------------------------
//th_borra_hijo
//-------------------------------------------------------------------
void posicion::th_borra_hijo (int Id_hijo)
{
int i,j;
for (i=0;i<n_hijos;i++)
if (hijo[i]==Id_hijo)
{
j=i;
for (i=j;i<n_hijos;i++) hijo[i]=hijo[i+1];
n_hijos--;
//cout<<"th_borra_hijo";
}
}
//-------------------------------------------------------------------
void posicion::debug_parentesco (void)
{
EnterCriticalSection (&CR_print);
int x=n_hijos;
for (int i=0;i<n_hijos;i++)
if (GLOBAL_TH[hijo[i]].padre!=Id)
{
cout<<endl;
cout<<"ERR: 034 "<<endl;
cout<<"nhijos="<<x<<endl;
cout<<"Id="<<Id<<endl;
cout<<"Padre del hijo de Id="<<GLOBAL_TH[hijo[i]].padre<<endl;
cout<<"nhijos="<<n_hijos<<endl;
for (int k=0;k<n_hijos;k++) cout<<GLOBAL_TH[hijo[i]].padre<<";";
cout<<endl;
getch ();
}
LeaveCriticalSection (&CR_print);
}
//-------------------------------------------------------------------
Code: Select all
#include "StdAfx.h"
#include "posicion.h"
#include "bitboards.h"
#include "recognicers.h"
#include "global.h"
#include "mt.h"
#include "hash.h"
#include "global.h"
#include "debug.h"
#include "consolecolors.h"
using namespace std;
//-------------------------------------------------------------------
//ALFABETA
//-------------------------------------------------------------------
int posicion::alfabeta (int beta,int depth,int tipo)
{
//-------------------------------------------------------------------
//TEMPO
//-------------------------------------------------------------------
test_tempo ();
//-------------------------------------------------------------------
//CUTTER
//-------------------------------------------------------------------
if (beta> 31500) return 31500;
if (beta<-31500) return -31500;
if (depth<=7) return qsearch (beta,depth,tipo);
//-------------------------------------------------------------------
//NODES
//-------------------------------------------------------------------
NODES++;
//-------------------------------------------------------------------
//REGLA 50 MOVIMIENTOS
//-------------------------------------------------------------------
if (mov100>99) return 0;
//-------------------------------------------------------------------
//REPETICIONES
//-------------------------------------------------------------------
if (repetido()) return 0;
//-------------------------------------------------------------------
int nueva_depth=0;
int enjaque=0;
int bestval =-32500;
int ev =-32500;
int ev2 =-32500;
int bestmove =0;
int R;
int aux100;
//-------------------------------------------------------------------
//HASH
//-------------------------------------------------------------------
int trans_depth=0;
int ttmove=0;
char dmx,dmi;
int max,min;
//-------------------------------------------------------------------
//HASH
//-------------------------------------------------------------------
//-------------------------------------------------------------------
//EVALUACION INTERNA
//-------------------------------------------------------------------
int eval_interna=evalua(0);
//-------------------------------------------------------------------
//NULL MOVE PRURING
//-------------------------------------------------------------------
//-------------------------------------------------------------------
//IID
//-------------------------------------------------------------------
//-------------------------------------------------------------------
//NUEVO NIVEL
//-------------------------------------------------------------------
btm=ttmove;
arbol_nuevo_nivel();
S->ttmove=btm;
S->pmov=0;
S->nmov=0;
S->capturas_excluidas=0;
S->underpromo_permited=0;
int nmovs=0;
//-------------------------------------------------------------------
//EXTENSION
//-------------------------------------------------------------------
int singular =0;
int extension=0;
//-------------------------------------------------------------------
//SEARCH
//-------------------------------------------------------------------
S->tipo_search=1;
int movimiento=0;
unsigned __int32 mov2=lista_data[lista_nmov-2].mov;
int org1;
int des1;
int org2;
int des2;
//-------------------------------------------------------------------
//BUCLE SEARCH
//-------------------------------------------------------------------
while ((movimiento=next_move_ab ())||(th_esperando_resultado ())||(th_resultados_disponibles (Id)))
{
//-------------------------------------------------------------------
//RESULTADOS DISPONIBLES
//-------------------------------------------------------------------
while (th_resultados_disponibles (Id))
{
int move_mt=0;
get_result (Id,ev,move_mt);
if (ev>bestval)
{
bestval=ev;
bestmove=move_mt;
if (ev>=beta)
{
stop_hijos ();
clean_results ();
if (turno) hash.admov_b (hash_key,bestmove,ev,depth);
else hash.admov_n (hash_key,bestmove,ev,depth);
if ((bestmove&(CAPTURA|ALPASO|PROMOCION))==0) arbol_add_killer (bestmove,depth);
arbol_borra_nivel();
btm=bestmove;
return ev;
}
}
}
//-------------------------------------------------------------------
//REPETITION PRURING
//-------------------------------------------------------------------
//-------------------------------------------------------------------
//MULTITHREAD
//-------------------------------------------------------------------
if ((movimiento)&&((tipo&1)==0))
if (split(movimiento,beta,depth,tipo,nmovs))
{
nmovs++;
goto BUCLE_MT;
}
//-------------------------------------------------------------------
//NORMAL SEARCH
//-------------------------------------------------------------------
if (movimiento)
{
ev=search_mt(movimiento,beta,depth,tipo,nmovs);
if ((movimiento&PROMOCION)&&(ev==0)) S->underpromo_permited=1;
desmueve();
nmovs++;
if (ev>bestval)
{
bestval=ev;
bestmove=movimiento;
if (ev>=beta)
{
stop_hijos ();
clean_results ();
if (turno) hash.admov_b (hash_key,bestmove,ev,depth);
else hash.admov_n (hash_key,bestmove,ev,depth);
if ((bestmove&(CAPTURA|ALPASO|PROMOCION))==0) arbol_add_killer (bestmove,depth);
arbol_borra_nivel();
btm=bestmove;
return ev;
}
}
}
//-------------------------------------------------------------------
BUCLE_MT:;
tipo&=6;
}
//-------------------------------------------------------------------
//STALEMATE
//-------------------------------------------------------------------
if (bestval==-32500)
{
btm=0;
arbol_borra_nivel();
return 0;
}
//-------------------------------------------------------------------
//FIN
//-------------------------------------------------------------------
if (turno) hash.admax_b (hash_key,bestval,depth);
else hash.admax_n (hash_key,bestval,depth);
arbol_borra_nivel();
return bestval;
}
//-------------------------------------------------------------------