Uri Blass wrote:strelka has the following code
Code: Select all
const unsigned char PawnPassedFile[8] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
My question is if it is not better to write simply (1<<) instead of an array.
Note that strelka is using often code like
(unsigned __int64)1 << sq instead of using an array setmask[sq]
I wonder if there is a speed reason to prefer an array when the array is arrays of chars of size 8 and to prefer 1<< when the array is array of 64 bit numbers of size 64.
Uri
It is likely negligible, specially if processing pawn-hashed stuff.
You may simply try both variations (or ignore it). It is about a good "balance" between memory lookup and computation for best scheduling and instructions per cycle. If you have high register pressure a lookup of 8 bytes is likely better.
Code: Select all
mov al, byte ptr [PawnPassedFile + ecx]
or with zero extension to eax
Code: Select all
movzx eax, byte ptr [PawnPassedFile + ecx]
If you have high memory pressure in some context, you may better use computation en-passant while "waiting" for some memory read/write.
Similar for single populated bitboards. In 32-bit mode is seems faster to use lookups:
Code: Select all
; 205 : if (att & (1 << k)) LineMask[3][i][j] |= (unsigned __int64)1 << sq;
0029e b8 01 00 00 00 mov eax, 1
002a3 8b cf mov ecx, edi
002a5 d3 e0 shl eax, cl
002a7 85 c5 test eax, ebp
002a9 74 1c je SHORT $L53879
002ab b8 01 00 00 00 mov eax, 1
002b0 33 d2 xor edx, edx
002b2 8b cb mov ecx, ebx
002b4 e8 00 00 00 00 call __allshl
002b9 8b 0e mov ecx, DWORD PTR [esi]
002bb 0b c8 or ecx, eax
002bd 8b 46 04 mov eax, DWORD PTR [esi+4]
002c0 0b c2 or eax, edx
002c2 89 0e mov DWORD PTR [esi], ecx
002c4 89 46 04 mov DWORD PTR [esi+4], eax
$L53879:
002c7 47 inc edi
002c8 83 eb 08 sub ebx, 8
002cb 83 ff 08 cmp edi, 8
002ce 7c ce jl SHORT $L53878
Btw. have you understood how the pawn-shield stuff works?