Stockfish Questions

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

User avatar
vittyvirus
Posts: 646
Joined: Wed Jun 18, 2014 2:30 pm
Full name: Fahad Syed

Stockfish Questions

Post 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...
mcostalba
Posts: 2684
Joined: Sat Jun 14, 2008 9:17 pm

Re: Stockfish Questions

Post 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 :-)
Sven
Posts: 4052
Joined: Thu May 15, 2008 9:57 pm
Location: Berlin, Germany
Full name: Sven Schüle

Re: Stockfish Questions

Post 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.
mcostalba
Posts: 2684
Joined: Sat Jun 14, 2008 9:17 pm

Re: Stockfish Questions

Post 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.
Henk
Posts: 7216
Joined: Mon May 27, 2013 10:31 am

Re: Stockfish Questions

Post 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.
mcostalba
Posts: 2684
Joined: Sat Jun 14, 2008 9:17 pm

Re: Stockfish Questions

Post 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.
Henk
Posts: 7216
Joined: Mon May 27, 2013 10:31 am

Re: Stockfish Questions

Post 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.
User avatar
vittyvirus
Posts: 646
Joined: Wed Jun 18, 2014 2:30 pm
Full name: Fahad Syed

Re: Stockfish Questions

Post 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
Sven
Posts: 4052
Joined: Thu May 15, 2008 9:57 pm
Location: Berlin, Germany
Full name: Sven Schüle

Re: Stockfish Questions

Post 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.
mcostalba
Posts: 2684
Joined: Sat Jun 14, 2008 9:17 pm

Re: Stockfish Questions

Post 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)