inline int CountDoubled(uint64_t boPawns)
{
int n = 0;
if((boPawns & ~(boPawns * BOARD_H_COL)) != boEmpty)
{
boPawns >>= 8;
uint64_t k = boEmpty;
for(int i = 0; i < 6; i++)
{
k |= (boPawns & BOARD_1_ROW); // accumula i bit dei pedoni sulla prima riga
uint64_t dbl = k & (boPawns >>= 8);
n += bits8[dbl];
}
}
return n;
}
(bits8 contains bits count for the first 256 integers)
According to VS profiler, the "if" takes about the same time as the whole loop!
inline int CountDoubled(uint64_t boPawns)
{
int n = 0;
boPawns >>= 8;
uint64_t k = boEmpty;
for(int i = 0; i < 6; i++)
{
k |= (boPawns & BOARD_1_ROW); // accumulates pawn bits on first row
uint64_t dbl = k & (boPawns >>= 8);
n += bits8[dbl];
}
return n;
}
Of course removing any test on pawns if there are no more one of them must be done in the caller.
The compiler is smart enough to avoid the "& BOARD_1_ROW" and it uses a single 8 bit register (r8b, in my test). An improvement using less smart compilers could be to use uint8_t variables for dbl and k.
hgm wrote:Normally this info would come from your Pawn hash, meaning that speed is irrelevant.
I've found a simpler way to do it: because I've a node array, I simply store the value of current pawn structure in the current node, so that I can use it avoiding re-computing any time: