Page 1 of 2

Stockfish Questions

Posted: Sat Feb 28, 2015 5:46 pm
by vittyvirus
I was looking at SF code to get some speed ups in perft and better eval in Yaka. Some questions:
file: position. cpp, function do_move()

Code: Select all

// Update incremental score
          st->psq += psq[us][promotion][to] - psq[us][PAWN][to];
psq[us][PAWN][to]; is always zero.

file: pawns.cpp, function evaluate()

Code: Select all

            b = pawn_attack_span(Us, s) & (ourPawns | theirPawns);
            b = pawn_attack_span(Us, s) & rank_bb(backmost_sq(Us, b));
WHAT??? :O
Sorry if I missed something...

Re: Stockfish Questions

Posted: Sat Feb 28, 2015 8:18 pm
by mcostalba
vittyvirus wrote:I was looking at SF code to get some speed ups in perft and better eval in Yaka. Some questions:
file: position. cpp, function do_move()

Code: Select all

// Update incremental score
          st->psq += psq[us][promotion][to] - psq[us][PAWN][to];
psq[us][PAWN][to]; is always zero.
Nice, thanks, good eye :-)
vittyvirus wrote: file: pawns.cpp, function evaluate()

Code: Select all

            b = pawn_attack_span(Us, s) & (ourPawns | theirPawns);
            b = pawn_attack_span(Us, s) & rank_bb(backmost_sq(Us, b));
WHAT??? :O
Sorry if I missed something...
rank_bb() expands again 'b', so you need to bitwise 'and' again ...eventually try to rewrite in a better way...if you find one :-)

Re: Stockfish Questions

Posted: Sun Mar 01, 2015 12:04 am
by Sven
mcostalba wrote:
vittyvirus wrote: file: pawns.cpp, function evaluate()

Code: Select all

            b = pawn_attack_span(Us, s) & (ourPawns | theirPawns);
            b = pawn_attack_span(Us, s) & rank_bb(backmost_sq(Us, b));
WHAT??? :O
Sorry if I missed something...
rank_bb() expands again 'b', so you need to bitwise 'and' again ...eventually try to rewrite in a better way...if you find one :-)
This should return the same result but might be more readable (despite the bigger number of characters):

Code: Select all

Rank ourRank   = rank_of(backmost_sq(Us, pawn_attack_span(Us, s) & ourPawns));
Rank theirRank = rank_of(backmost_sq(Us, pawn_attack_span(Us, s) & theirPawns));
backward = &#40;Us == WHITE&#41; ? &#40;theirRank <= ourRank + 1&#41; &#58; &#40;theirRank >= ourRank - 1&#41;;
as opposed to the original:

Code: Select all

b = pawn_attack_span&#40;Us, s&#41; & &#40;ourPawns | theirPawns&#41;;
b = pawn_attack_span&#40;Us, s&#41; & rank_bb&#40;backmost_sq&#40;Us, b&#41;);
backward = &#40;b | shift_bb<Up>&#40;b&#41;) & theirPawns;
I don't know which one is faster.

Re: Stockfish Questions

Posted: Sun Mar 01, 2015 11:00 am
by mcostalba
Sven Schüle wrote: I don't know which one is faster.
It's faster and shorter the original :-)

Anyhow thanks for this attempt.

Re: Stockfish Questions

Posted: Sun Mar 01, 2015 11:06 am
by Henk
Sven Schüle wrote:
mcostalba wrote:
vittyvirus wrote: file: pawns.cpp, function evaluate()

Code: Select all

            b = pawn_attack_span&#40;Us, s&#41; & &#40;ourPawns | theirPawns&#41;;
            b = pawn_attack_span&#40;Us, s&#41; & rank_bb&#40;backmost_sq&#40;Us, b&#41;);
WHAT??? :O
Sorry if I missed something...
rank_bb() expands again 'b', so you need to bitwise 'and' again ...eventually try to rewrite in a better way...if you find one :-)
This should return the same result but might be more readable (despite the bigger number of characters):

Code: Select all

Rank ourRank   = rank_of&#40;backmost_sq&#40;Us, pawn_attack_span&#40;Us, s&#41; & ourPawns&#41;);
Rank theirRank = rank_of&#40;backmost_sq&#40;Us, pawn_attack_span&#40;Us, s&#41; & theirPawns&#41;);
backward = &#40;Us == WHITE&#41; ? &#40;theirRank <= ourRank + 1&#41; &#58; &#40;theirRank >= ourRank - 1&#41;;
as opposed to the original:

Code: Select all

b = pawn_attack_span&#40;Us, s&#41; & &#40;ourPawns | theirPawns&#41;;
b = pawn_attack_span&#40;Us, s&#41; & rank_bb&#40;backmost_sq&#40;Us, b&#41;);
backward = &#40;b | shift_bb<Up>&#40;b&#41;) & theirPawns;
I don't know which one is faster.
I don't understand anything of it. Perhaps normal english explanation would help. Even don't know what it is all about. Maybe that's why I don't study Stockfish code for it is too difficult for me to understand. Or perhaps I don't want to spend so much time on it trying to understand it.

Re: Stockfish Questions

Posted: Sun Mar 01, 2015 11:18 am
by mcostalba
Henk wrote: I don't understand anything of it.
That's for sure.
Henk wrote: Perhaps normal english explanation would help.
Whay should I help you? you are just a troll pretending to be an engine author when you even didn't know what an engine is (very possibly you even don't know how to program). I don'tunderstand what's the point of posting nonsense here, if you would be interested in the subject probably you would try to mock up something, like a legal move generator, just to start, so I think you are not even interested in the subject, you post just for trolling.

Re: Stockfish Questions

Posted: Sun Mar 01, 2015 11:30 am
by Henk
mcostalba wrote:
Henk wrote: I don't understand anything of it.
That's for sure.
Henk wrote: Perhaps normal english explanation would help.
Whay should I help you? you are just a troll pretending to be an engine author when you even didn't know what an engine is (very possibly you even don't know how to program). I don'tunderstand what's the point of posting nonsense here, if you would be interested in the subject probably you would try to mock up something, like a legal move generator, just to start, so I think you are not even interested in the subject, you post just for trolling.
Yes and I am a liar too. Please don't waste your time on me. I also only want to talk to troll friends.

Re: Stockfish Questions

Posted: Sun Mar 01, 2015 2:15 pm
by vittyvirus
Henk wrote:
Sven Schüle wrote:
mcostalba wrote:
vittyvirus wrote: file: pawns.cpp, function evaluate()

Code: Select all

            b = pawn_attack_span&#40;Us, s&#41; & &#40;ourPawns | theirPawns&#41;;
            b = pawn_attack_span&#40;Us, s&#41; & rank_bb&#40;backmost_sq&#40;Us, b&#41;);
WHAT??? :O
Sorry if I missed something...
rank_bb() expands again 'b', so you need to bitwise 'and' again ...eventually try to rewrite in a better way...if you find one :-)
This should return the same result but might be more readable (despite the bigger number of characters):

Code: Select all

Rank ourRank   = rank_of&#40;backmost_sq&#40;Us, pawn_attack_span&#40;Us, s&#41; & ourPawns&#41;);
Rank theirRank = rank_of&#40;backmost_sq&#40;Us, pawn_attack_span&#40;Us, s&#41; & theirPawns&#41;);
backward = &#40;Us == WHITE&#41; ? &#40;theirRank <= ourRank + 1&#41; &#58; &#40;theirRank >= ourRank - 1&#41;;
as opposed to the original:

Code: Select all

b = pawn_attack_span&#40;Us, s&#41; & &#40;ourPawns | theirPawns&#41;;
b = pawn_attack_span&#40;Us, s&#41; & rank_bb&#40;backmost_sq&#40;Us, b&#41;);
backward = &#40;b | shift_bb<Up>&#40;b&#41;) & theirPawns;
I don't know which one is faster.
I don't understand anything of it. Perhaps normal english explanation would help. Even don't know what it is all about. Maybe that's why I don't study Stockfish code for it is too difficult for me to understand. Or perhaps I don't want to spend so much time on it trying to understand it.
The reason why I like SF the most is because of clean code. I agree that you need some knowledge of what is being done, but not too much

Re: Stockfish Questions

Posted: Sun Mar 01, 2015 2:30 pm
by Sven
mcostalba wrote:
Sven Schüle wrote: I don't know which one is faster.
It's faster and shorter the original :-)

Anyhow thanks for this attempt.
You may be right, but just for curiosity: how did you come to that conclusion?

"Shorter" is certainly right, even if I rename some identifiers longer than 2 chars. My argument was "better readability" which is not always equivalent to "less characters".

And "faster"? How would you explain it? I could imagine that in my proposal the first and the second line are fully independent calculations so the CPU could possibly execute the whole piece of code with less cycles. Furthermore I think it has less memory access (no need to access the RankBB array) and also less operations (the original has a couple of and/or/shift). Both are branchless (the ?: is resolved by the compiler due to "Us" being a template parameter). What would make the original faster? One more LSB/MSB operation? That is the only reason I could imagine.

This is not an important issue, for sure, since the differences are negligible and would never justify a change of the working code. I just ask to understand better your reasoning.

Re: Stockfish Questions

Posted: Sun Mar 01, 2015 5:53 pm
by mcostalba
Here is the disassembly of 2 solutions (MSVC 2013)

Code: Select all

            // We now know there are no friendly pawns beside or behind this
            // pawn on adjacent files. We now check whether the pawn is
            // backward by looking in the forward direction on the adjacent
            // files, and picking the closest pawn there.
            b = pawn_attack_span&#40;Us, s&#41; & &#40;ourPawns | theirPawns&#41;;
000000013F7CBE22  mov         r9,qword ptr &#91;r11+rdx+2269E0h&#93;  
000000013F7CBE2A  mov         rax,r12  
000000013F7CBE2D  or          rax,rsi  
000000013F7CBE30  and         rax,r9  
            b = pawn_attack_span&#40;Us, s&#41; & rank_bb&#40;backmost_sq&#40;Us, b&#41;);
000000013F7CBE33  bsf         rax,rax  
000000013F7CBE37  movsxd      rcx,eax  
000000013F7CBE3A  sar         rcx,3  
000000013F7CBE3E  mov         rdx,qword ptr &#91;rdx+rcx*8+13B6A0h&#93;  
000000013F7CBE46  and         rdx,r9  

            // If we have an enemy pawn in the same or next rank, the pawn is
            // backward because it cannot advance without being captured.
            backward = &#40;b | shift_bb<Up>&#40;b&#41;) & theirPawns;
000000013F7CBE49  movzx       r9d,byte ptr &#91;e&#93;  
000000013F7CBE4F  mov         rax,rdx  
000000013F7CBE52  shl         rax,8  
000000013F7CBE56  or          rax,rdx  
000000013F7CBE59  test        r12,rax  
000000013F7CBE5C  setne       r12b  
000000013F7CBE60  jmp         `anonymous namespace'&#58;&#58;evaluate<0>+1F5h &#40;013F7CBE65h&#41;  
and yours:

Code: Select all

            // We now know there are no friendly pawns beside or behind this
            // pawn on adjacent files. We now check whether the pawn is
            // backward by looking in the forward direction on the adjacent
            // files, and picking the closest pawn there.
            Rank ourRank = rank_of&#40;backmost_sq&#40;Us, pawn_attack_span&#40;Us, s&#41; & ourPawns&#41;);
000000013F7CBE25  mov         rcx,qword ptr &#91;r10+rax+2269E0h&#93;  
000000013F7CBE2D  mov         rax,rcx  
000000013F7CBE30  and         rcx,qword ptr &#91;rsp+78h&#93;  
000000013F7CBE35  and         rax,rdi  
000000013F7CBE38  bsf         rdx,rax  
            Rank theirRank = rank_of&#40;backmost_sq&#40;Us, pawn_attack_span&#40;Us, s&#41; & theirPawns&#41;);
000000013F7CBE3C  bsf         rax,rcx  
000000013F7CBE40  sar         edx,3  
000000013F7CBE43  sar         eax,3  
            backward = &#40;Us == WHITE&#41; ? &#40;theirRank <= ourRank + 1&#41; &#58; &#40;theirRank >= ourRank - 1&#41;;
000000013F7CBE46  inc         edx  
000000013F7CBE48  cmp         eax,edx  
000000013F7CBE4A  setle       bpl  
000000013F7CBE4E  jmp         `anonymous namespace'&#58;&#58;evaluate<0>+1E3h &#40;013F7CBE53h&#41;  
            backward = false;
000000013F7CBE50  xor         bpl,bpl 
Sorry I didn't do any speed test, also because you version is not functionally equivalent with original (bench signature of 7657127 instead of 8285241)