Page 1 of 4
question about symmertic evaluation
Posted: Wed May 23, 2007 9:53 pm
by Uri Blass
I found that my evaluation is not symmetric for white and black.
one of the reason is that in some part of my evaluation I simply calculate score from white point of view and later divide by 8
now (14>>3)=1 and (-14>>3)=-2 so I can get a different number
for white and black.
My question is how do you solve that type of problem and if there is a way to solve it without doing the code slower(of course it is easy to solve it by doing the code slower and writing something like
if (score<0)
{
score=-score;
score=score>>3;
score=-score;
}
else
score=score>>3;
I thought also about using (score+4)>>3 but in that case (12+4)>>3=2
when (-12+4)>>3=-1
Uri
Re: question about symmertic evaluation
Posted: Wed May 23, 2007 10:45 pm
by Uri Blass
The best thing that I can think about is something like this
Code: Select all
if (score>0)
score+=4;
else
score+=3;
return (score>>3);
I wonder if you have better idea how to make it symmetric for score=X and score=-X
Maybe there is a simple library function of division that is faster
Re: question about symmertic evaluation
Posted: Wed May 23, 2007 10:46 pm
by Gerd Isenberg
One idea is to avoid the asymmetrical arithmetical shift right 3 at all and to mul all other eval aspects by 8. You may add 7 if the value to shift arithmetical right 3 is negative, but this is of course more expensive.
Code: Select all
symmetrical arithmetical shift right 3 ::= (x + ((x>>31)&7)) >> 3
or with respect to the value range:
Code: Select all
symmetrical arithmetical shift right 3 ::= (x + ((unsigned)x>>29)) >> 3
The common approach seems to score and aggregate from white resp. black point of view and keep both values in evalScore[2] to divide both before the final difference for color's point of view:
Code: Select all
posEval = (evalScore[color]>>3) - (evalScore[color^1]>>3);
Gerd
Re: question about symmertic evaluation
Posted: Wed May 23, 2007 11:04 pm
by Uri Blass
Gerd Isenberg wrote:One idea is to avoid the asymmetrical arithmetical shift right 3 at all and to mul all other eval aspects by 8. You may add 7 if the value to shift arithmetical right 3 is negative, but this is of course more expensive.
Code: Select all
symmetrical arithmetical shift right 3 ::= (x + ((x>>31)&7)) >> 3
or with respect to the value range:
Code: Select all
symmetrical arithmetical shift right 3 ::= (x + ((unsigned)x>>29)) >> 3
The common approach seems to score and aggregate from white resp. black point of view and keep both values in evalScore[2] to divide both before the final difference for color's point of view:
Code: Select all
posEval = (evalScore[color]>>3) - (evalScore[color^1]>>3);
Gerd
Thanks
Here is the full code that caused the problem and is about prefering pawns in the endgame
Code: Select all
static int evalpawnrelative(void)
{
int score=0;
if (numpawns[LIGHT]!=numpawns[DARK])
{
score=(24-valuepieces)*(numpawns[LIGHT]-numpawns[DARK]);
return (score>>3)*prefer_pawns_in_end_games;
}
return 0;
}
valuepieces can be bigger than 24 in the opening or smaller than 24 in the endgame.
The default value of prefer_pawns_in_the end_games is 1
practically the score that it returns is between -0.0475 per pawn advantage in the opening and 0.03 per pawn advantage in pawn endgames.
I can make 2 tables for pawns in the endgame and in the opening but I am not sure if it is a good idea because in many positions the number of pawns of both sides is equal so calculating 2 piece square tables when the difference between them is constant seems to be a waste of time.
Maybe I care too much about small speed change that is not very important and it is not that I really care about speed but simply that I do not like my program to be slower because of fixing a bug.
Uri
Re: question about symmertic evaluation
Posted: Wed May 23, 2007 11:50 pm
by bob
just don't use shift as it is not correct for positive and negative numbers.
Re: question about symmertic evaluation
Posted: Wed May 23, 2007 11:51 pm
by bob
Gerd Isenberg wrote:One idea is to avoid the asymmetrical arithmetical shift right 3 at all and to mul all other eval aspects by 8. You may add 7 if the value to shift arithmetical right 3 is negative, but this is of course more expensive.
Code: Select all
symmetrical arithmetical shift right 3 ::= (x + ((x>>31)&7)) >> 3
or with respect to the value range:
Code: Select all
symmetrical arithmetical shift right 3 ::= (x + ((unsigned)x>>29)) >> 3
The common approach seems to score and aggregate from white resp. black point of view and keep both values in evalScore[2] to divide both before the final difference for color's point of view:
Code: Select all
posEval = (evalScore[color]>>3) - (evalScore[color^1]>>3);
Gerd
I'd be willing to bet that a plain divide will not noticably affect his overall search speed. And it will solve this correctly.
Re: question about symmertic evaluation
Posted: Thu May 24, 2007 12:04 am
by Uri Blass
bob wrote:Gerd Isenberg wrote:One idea is to avoid the asymmetrical arithmetical shift right 3 at all and to mul all other eval aspects by 8. You may add 7 if the value to shift arithmetical right 3 is negative, but this is of course more expensive.
Code: Select all
symmetrical arithmetical shift right 3 ::= (x + ((x>>31)&7)) >> 3
or with respect to the value range:
Code: Select all
symmetrical arithmetical shift right 3 ::= (x + ((unsigned)x>>29)) >> 3
The common approach seems to score and aggregate from white resp. black point of view and keep both values in evalScore[2] to divide both before the final difference for color's point of view:
Code: Select all
posEval = (evalScore[color]>>3) - (evalScore[color^1]>>3);
Gerd
I'd be willing to bet that a plain divide will not noticably affect his overall search speed. And it will solve this correctly.
thanks
It seems that replacing some >> by / solves the problem
of anti-symmetric evaluation and now at least for the wac positions my evaluation is symmetric between white and black(did not check symmetry between left and right)
Uri
Re: question about symmertic evaluation
Posted: Thu May 24, 2007 12:09 am
by Gerd Isenberg
bob wrote:
I'd be willing to bet that a plain divide will not noticably affect his overall search speed. And it will solve this correctly.
Idiv is still quite expensive (idiv r32/imm ~18-42 cycles on core2 duo) - but if seldomly used it does not hurt. Anyway, vc2005 seems aware of that trick:
Code: Select all
int idiv8(int x)
{
return x / 8;
}
mov eax, ecx
cdq
and edx, 7
add eax, edx
sar eax, 3
Re: question about symmertic evaluation
Posted: Thu May 24, 2007 2:01 am
by bob
Gerd Isenberg wrote:bob wrote:
I'd be willing to bet that a plain divide will not noticably affect his overall search speed. And it will solve this correctly.
Idiv is still quite expensive (idiv r32/imm ~18-42 cycles on core2 duo) - but if seldomly used it does not hurt. Anyway, vc2005 seems aware of that trick:
Code: Select all
int idiv8(int x)
{
return x / 8;
}
mov eax, ecx
cdq
and edx, 7
add eax, edx
sar eax, 3
The thing is it interlaces nicely with other instructions around it... I have been using several divides in my code to scale parts of the evaluation, and it made absolutely no difference in my NPS...
Re: question about symmertic evaluation
Posted: Thu May 24, 2007 5:42 am
by sje
bob wrote:I'd be willing to bet that a plain divide will not noticably affect his overall search speed. And it will solve this correctly.
Agreed. Furthermore, a decent optimizing compiler will code a power of two division as a right shift where it is possible (and correct) to do so.