Page 1 of 2

about stockfish and logic

Posted: Sat Apr 17, 2010 8:53 am
by Uri Blass
I read the following comment in stockfish(lines 1335-1336 of search.cpp):

// Logically we should return (v + razor_margin(depth)), but
// surprisingly this did slightly weaker in tests.


I see no reason why logically you need to return a different number than the number that you got by search.

It is correct that v is based on search to reduced depth but it is still result based on search.

When you do reductions you do not store different value than the value that you got by search so I see no reason why it should be different for pruning.

I wonder if it is not better to replace
return refinedValue - futility_margin(depth, 0);
by return refinedValue in step 7.

Did you test and find that refinedValue-futility_margin(depth,0) is better?

Uri

Re: about stockfish and logic

Posted: Sat Apr 17, 2010 12:34 pm
by zamar
Uri Blass wrote:I read the following comment in stockfish(lines 1335-1336 of search.cpp):

// Logically we should return (v + razor_margin(depth)), but
// surprisingly this did slightly weaker in tests.
It was tested and written by me.
I see no reason why logically you need to return a different number than the number that you got by search.
It's a common practice when doing a futility pruning (and there is a good reason for it). IMO razoring is just futility pruning "other way around".

When you do reductions you do not store different value than the value that you got by search so I see no reason why it should be different for pruning.
Reductions are invariant to static value, so this is a completely different thing. For futility pruning/razoring, It's important to understand the interactions through TT and what happens when parent node gets probed from TT with different beta.
I wonder if it is not better to replace
return refinedValue - futility_margin(depth, 0);
by return refinedValue in step 7.

Did you test and find that refinedValue-futility_margin(depth,0) is better?

Uri
No we haven't tested it, but I'd bet that it's not a big deal, hard to measure.

If you have extra time, please test :) If you are interested in this, I can give instructions through pm. Proper testing of the patch will take 24-30h.

Re: about stockfish and logic

Posted: Sat Apr 17, 2010 5:49 pm
by Ralph Stoesser
I also have a question regarding step 6: razoring.
In case the razoring conditions are true the qsearch value v is returned. Shouldn't refinedValue be more accurate than v, in case refinedEval would come from a TT entry with depth>0?

Re: about stockfish and logic

Posted: Sun Apr 18, 2010 7:40 am
by mcostalba
Ralph Stoesser wrote:I also have a question regarding step 6: razoring.
In case the razoring conditions are true the qsearch value v is returned. Shouldn't refinedValue be more accurate than v, in case refinedEval would come from a TT entry with depth>0?
Could you please post the code you mean to change and the change you are suggesting ? It is not clear to me from the above what is the idea.

Thanks
Marco

Re: about stockfish and logic

Posted: Sun Apr 18, 2010 8:09 am
by Uri Blass
mcostalba wrote:
Ralph Stoesser wrote:I also have a question regarding step 6: razoring.
In case the razoring conditions are true the qsearch value v is returned. Shouldn't refinedValue be more accurate than v, in case refinedEval would come from a TT entry with depth>0?
Could you please post the code you mean to change and the change you are suggesting ? It is not clear to me from the above what is the idea.

Thanks
Marco
I understand that the idea is simply to return tranposition table score instead of doing qsearch in case that there is information in the hash.

I guess that the idea is not good because qsearch already call the tranposition table so you earn nothing from it.

Uri

Re: about stockfish and logic

Posted: Sun Apr 18, 2010 11:32 am
by Ralph Stoesser
Uri Blass wrote:
mcostalba wrote:
Ralph Stoesser wrote:I also have a question regarding step 6: razoring.
In case the razoring conditions are true the qsearch value v is returned. Shouldn't refinedValue be more accurate than v, in case refinedEval would come from a TT entry with depth>0?
Could you please post the code you mean to change and the change you are suggesting ? It is not clear to me from the above what is the idea.

Thanks
Marco
I understand that the idea is simply to return tranposition table score instead of doing qsearch in case that there is information in the hash.

I guess that the idea is not good because qsearch already call the tranposition table so you earn nothing from it.

Uri
I was thinking about something like this

Code: Select all

    // Step 6. Razoring
    if (    refinedValue < beta - razor_margin&#40;depth&#41;
        &&  ttMove == MOVE_NONE
        &&  ss&#91;ply - 1&#93;.currentMove != MOVE_NULL
        &&  depth < RazorDepth
        && !isCheck
        && !value_is_mate&#40;beta&#41;
        && !pos.has_pawn_on_7th&#40;pos.side_to_move&#40;)))
    &#123;
    	if &#40;refinedValue == ss&#91;ply&#93;.eval&#41; // refinedValue is static eval score
    	&#123;
    		Value rbeta = beta - razor_margin&#40;depth&#41;;
    		Value v = qsearch&#40;pos, ss, rbeta-1, rbeta, Depth&#40;0&#41;, ply, threadID&#41;;
    		if &#40;v < rbeta&#41;
    			// Logically we should return &#40;v + razor_margin&#40;depth&#41;), but
    			// surprisingly this did slightly weaker in tests.
    			return v;
    	&#125;
    	else // refinedValue is TT score
    	&#123;
    		return refinedValue;
    	&#125;
    &#125;
Yes, Uri, qsearch would retrieve the better score from TT.
So we would only save a TT query and a call to qsearch in this case.
It's probably not worth to do so.

Re: about stockfish and logic

Posted: Sun Apr 18, 2010 11:49 am
by mcostalba
Ralph Stoesser wrote: Yes, Uri, qsearch would retrieve the better score from TT.
So we would only save a TT query and a call to qsearch in this case.
It's probably not worth to do so.
I think so too.

Instead a possible optimization that I didn't make because of didn't find a nice way to do it (read "without changing qsearch() call parameters") is to pass the static position evaluation to qsearch when we razor.

IOW we have already called the costly evaluate() few lines before:

Code: Select all

ss&#91;ply&#93;.eval = evaluate&#40;pos, ei, threadID&#41;;
and now we are going to call qsearch that, if doesn't return immediately after a TT hit, is going to call _again_ evaluate() on the same position, but in this case we could "pass" to qsearch the already calculated score and avoid the second redundant call.

Someone has hints (read "a patch") to how to do it ?

Re: about stockfish and logic

Posted: Sun Apr 18, 2010 12:19 pm
by Michel
going to call _again_ evaluate() on the same position,

Isn't this exactly what an evaluation cache is for? So that you don't have to think about such things.

Re: about stockfish and logic

Posted: Sun Apr 18, 2010 12:26 pm
by mcostalba
Michel wrote:
going to call _again_ evaluate() on the same position,

Isn't this exactly what an evaluation cache is for? So that you don't have to think about such things.
Do we have an evaluation cache ? :?: :?: :?:


BTW, I _want_ to think about such things because I want to always have very clear the impact of a change against the benefit....if you are suggesting to implement an evaluation cache to optimize the qsearch call in razoring _perhaps_ you don't have clear such cost/benefit relation.

...and I think we all agree that a possible answer like: "but there are other places where an evaluation cache could be useful" has _absolutely_ no meaning as is, i.e. without evidences support (it would be just a no-content discussion like the one on object oriented languages taking place in the main forum)...sorry to point out this obvious point but you know, better safe then sorry :-)

Re: about stockfish and logic

Posted: Sun Apr 18, 2010 2:25 pm
by michiguel
mcostalba wrote:
Michel wrote:
going to call _again_ evaluate() on the same position,

Isn't this exactly what an evaluation cache is for? So that you don't have to think about such things.
Do we have an evaluation cache ? :?: :?: :?:


BTW, I _want_ to think about such things because I want to always have very clear the impact of a change against the benefit....if you are suggesting to implement an evaluation cache to optimize the qsearch call in razoring _perhaps_ you don't have clear such cost/benefit relation.
You do not need a full blown hash table. You just need to remember one entry with last_eval and last_hashsignature. This approach could also be useful with pawn scores (before even going to a hash pawn table).

Miguel

...and I think we all agree that a possible answer like: "but there are other places where an evaluation cache could be useful" has _absolutely_ no meaning as is, i.e. without evidences support (it would be just a no-content discussion like the one on object oriented languages taking place in the main forum)...sorry to point out this obvious point but you know, better safe then sorry :-)