Stan Arts wrote:Hi Daniel,
Most likely the values are so close because it seems you are searching only very few positions? So the hashtable gets no where near full even with 64MB.
Try searching much much longer to see a clearer difference in efficiency.
Positions found vs tested seems normal at first glance. Ie. You would get say 4x as many leafnodes each time that you haven't encountered before and are not in hash even with massive transpositions. (It's not a closed position, white is winning so it's looking at new variations with a queen on etc. where the transpositions get way lower.)
But I don't know why you are saving only 20-ish percent instead of atleast as many as tested positions. You don't store everything? Do you test in Qsearch but not store? Or does saved mean positions where you get a cutoff. I might misunderstand your numbers.
Well thank you stan for some hints but I had a display bug , fixed now, here is the real search infos for the position :
Code: Select all
TIME 5 seconds / moves
Hashsize = 64mb
depth = 29 , eval = +13.32 , nodes = 258496 , qnodes = 863
pv = f3e3 e8f7 e3d2 f7f8 d2c2 f8f7 c2b2 f7f8 b2a3 f8f7 a3b4 f7f8 b4c5
f8e8 c5d6 e8f7 d6d7 f7f8 d7e6 f8e8 f6f7 e8f8 e6d7 f8f7 e5e6 f7f8 e6e7
f8g7 e7e8Q g7h7 d7e6 h7g7 e6d5 g7h7 d5c4
hash :
tested = 159599, found = 79244, saved = 67266
Hashsize = 128mb
depth = 29 , eval = +13.32 , nodes = 257867 , qnodes = 861
pv = f3e3 e8f7 e3d2 f7f8 d2c2 f8f7 c2b2 f7f8 b2a3 f8f7 a3b4 f7f8 b4c5
f8e8 c5d6 e8f7 d6d7 f7f8 d7e6 f8e8 f6f7 e8f8 e6d7 f8f7 e5e6 f7f8 e6e7
f8g7 e7e8Q g7h7 d7e6 h7g7 e6d5 g7h7 d5c4
hash :
tested = 159440, found = 79187, saved = 67170
Hashsize = 256
depth = 29 , eval = +13.32 , nodes = 258099 , qnodes = 863
pv = f3e3 e8f7 e3d2 f7f8 d2c2 f8f7 c2b2 f7f8 b2a3 f8f7 a3b4 f7f8 b4c5
f8e8 c5d6 e8f7 d6d7 f7f8 d7e6 f8e8 f6f7 e8f8 e6d7 f8f7 e5e6 f7f8 e6e7
f8g7 e7e8Q g7h7 d7e6 h7g7 e6d5 g7h7 d5c4
hash :
tested 159488, found = 79274, saved = 67165
And yes I'm so disapointed when I look at my résults , no improvment for more Hashsize ...
And yes , I don't know why it save not much positions in the ttable ...
I'm so lost in the TT labyrinth now lol
her is my alpha beta / pvs code , If you look at it you can see I save hash positions when cut off , mate found , stale mate too and at the end of the function
Code: Select all
//----------------------------------------------------------------------------------------------------------------
// alpha beta + PVS
//----------------------------------------------------------------------------------------------------------------
int pvs(int alpha, int beta, int depth, MOVE * pBestMove, bool nulmove, int extension)
{
int i,j;
int value;
int havemove;
int movecnt;
int hashf = hashfALPHA;
int rep;
bool echec = FAUX;
bool echec2 = FAUX;
bool ext = FAUX;
int ply = 0;
MOVE moveBuf[200];
MOVE tmpMove;
int margin[4] = {0, 125, 325, 525};
int score;
bool prune = FAUX;
//-----------------------------------------------------------------
// controle temps depasse ou non (jeu au temps)
//-----------------------------------------------------------------
fin_recherche = controle_si_temps_depasse();
if(fin_recherche)
return 0;
//-----------------------------------------------------------------
// longueur pv
//-----------------------------------------------------------------
long_pv[prof] = prof;
//-----------------------------------------------------------------
// profondeur limite ateinte : retourne eval()
//-----------------------------------------------------------------
if(prof >= MAXPLY-1)
return eval();
//-----------------------------------------------------------------
// nulle règle des 50 coups? ?
//-----------------------------------------------------------------
if(cinquante == 100)
{
return 0;
}
//-----------------------------------------------------------------
// nulle règle des triples répétitions ?
//-----------------------------------------------------------------
rep = triple_repetition();
if(prof && rep)
{
return 0;
}
//-----------------------------------------------------------------
// extension d'une profondeur si la couleur en cours est en échec
//-----------------------------------------------------------------
echec = roi_attaque(pos_roi[side], side);
if(echec)
{
depth++;
}
//-----------------------------------------------------------------
// extension d'une profondeur si le coup précédent a été une promotion
// ou une avance de pion à la 7eme rangée
//-----------------------------------------------------------------
if(extension)
depth++;
//-----------------------------------------------------------------
// on ateint la profondeur en cours quiescence
//-----------------------------------------------------------------
if(depth <= 0)
{
value = quiesce(alpha, beta, &tmpMove);
return value;
}
//-----------------------------------------------------------------
// position dans la table de hashage ?
//-----------------------------------------------------------------
if(hash_ok)
{
if(prof)
{
value = probe_hash(depth, alpha, beta);
if(value != valINCONNUE)
{
return value;
}
}
}
//-----------------------------------------------------------------
// FUTILITY PRUNING
// conditions : depth >0 et < 4 , !echec , !pv
//-----------------------------------------------------------------
if((!echec) && (!follow_pv) && (depth > 0 && depth < 4) && (!extension))
{
score = eval();
if(score <= alpha-margin[depth])
return (quiesce(alpha, beta, &tmpMove));
if(score >= beta+margin[depth])
return beta;
}
//-----------------------------------------------------------------
// NULLMOVE
// conditions : pas de finale de pion
// pas en échec
// profondeur >=2
//-----------------------------------------------------------------
if(nm_ok)
{
if((!echec) && (ok_pour_nul_move()) && (depth >= 2) && (nulmove) && (!follow_pv) && (!extension))
{
++ctr_nm;
//printf("ok pour null move (echec : %d phase : %d (ok_pour_nul_move() : %d) prof : %d nulmove : %d)\n",
//echec,PHASE,ok_pour_nul_move(),prof,nulmove);
jouer_coup_nul();
value = -pvs(-beta, -(beta-1), depth - NULL_DEPTH - 1, &tmpMove, NO_NULL, FAUX);
dejouer_coup_nul();
if (value >= beta)
{
return beta;
}
}
}
//-----------------------------------------------------------------
// init du pointeur et flag "au moins un coup jouable"
//-----------------------------------------------------------------
havemove = 0;
pBestMove->type = COUP_VIDE;
//-----------------------------------------------------------------
// génération des coups pseudo-légaux
//-----------------------------------------------------------------
movecnt = gen_coups(side, moveBuf);
if(follow_pv)
tri_pv(moveBuf, movecnt);
//-----------------------------------------------------------------
// boucle coups normaux
//-----------------------------------------------------------------
for (i = 0; i < movecnt; ++i)
{
ext = FAUX;
meilleur_coup_suivant(moveBuf, movecnt, i);
if (jouer_coup(moveBuf[i]))
{
continue;
}
echec2 = roi_attaque(pos_roi[side], side);
havemove++;
nodes++;
//extension si pion avance a la 7eme rangée (et coup non réduit lmr)
if(moveBuf[i].piece_from == PION && (ROW(moveBuf[i].dest) == 1 || ROW(moveBuf[i].dest) == 6))
ext = VRAI;
//extension si promotion
if(PROMO(moveBuf[i].type))
ext = VRAI;
if(havemove == 1)
{
value = -pvs(-beta, -alpha, depth - 1, &tmpMove, OK_NULL, ext);
}
else
{
//------------------------------------------------------
// lmr possible?
//------------------------------------------------------
if(lmr_ok)
{
if((prof >= START_PROF) && (!echec) && (!echec2) && (!ext) &&
(!follow_pv) && (moveBuf[i].type == NORMAL))
{
if(havemove > 5)
{
if(moveBuf[i].evaluation < 50000)
value = -pvs(-(alpha+1), -alpha, (depth - 3) , &tmpMove, OK_NULL, ext);
else
value = -pvs(-(alpha+1), -alpha, (depth - 2) , &tmpMove, OK_NULL, ext);
}
else
value = -pvs(-(alpha+1), -alpha, (depth - 1) , &tmpMove, OK_NULL, ext);
}
else
{
value = alpha + 1;
}
if(value > alpha)
{
++ctr_pvs;
value = -pvs(-(alpha+1), -alpha, depth - 1, &tmpMove, NO_NULL, ext);
if(value > alpha && value < beta)
{
value = -pvs(-beta, -alpha, depth - 1, &tmpMove, OK_NULL, ext);
}
}
}
else
{
++ctr_pvs;
value = -pvs(-(alpha+1), -alpha, depth - 1, &tmpMove, NO_NULL, ext);
if(value > alpha && value < beta)
{
value = -pvs(-beta, -alpha, depth - 1, &tmpMove, OK_NULL, ext);
}
}
}
dejouer_coup();
if (value > alpha)
{
history[moveBuf[i].from][moveBuf[i].dest] += (prof * prof);
if(history[moveBuf[i].from][moveBuf[i].dest] >= 999999)
history[moveBuf[i].from][moveBuf[i].dest] = 999999;
if(max_hh < history[moveBuf[i].from][moveBuf[i].dest])
{
max_hh = history[moveBuf[i].from][moveBuf[i].dest];
}
*pBestMove = moveBuf[i];
if (value >= beta) //" cutoff "
{
save_hash(depth, beta, hashfBETA, pBestMove);
if(moveBuf[i].type < PROMO_CAVALIER)
{
killer2[prof] = killer1[prof];
killer1[prof] = moveBuf[i];
}
return beta;
}
hashf = hashfEXACT;
alpha = value;
//-----------------------------------------------------------------
// mise a jour pv
//-----------------------------------------------------------------
pv[prof][prof] = *pBestMove;
for (j = prof + 1; j < long_pv[prof + 1]; ++j)
{
pv[prof][j] = pv[prof + 1][j];
}
long_pv[prof] = long_pv[prof + 1];
}
}
//-----------------------------------------------------------------
// si aucun coups , situation de MAT ou de PAT
//-----------------------------------------------------------------
if (!havemove)
{
if (roi_attaque(pos_roi[side], side))
{
save_hash(depth, -MATE + prof, hashf, pBestMove);
return -MATE + prof;
}
else
{
save_hash(depth, 0, hashf, pBestMove);
return 0;
}
}
save_hash(depth, alpha, hashf, pBestMove);
return alpha;
}
[/b]