Skip to content

Commit 35a0820

Browse files
committed
Double magics generation speed
Profiling shows that resetting attacks table after a failed candidate magic attempt is the biggest time consumer, so rewrite the logic avoiding the memset() Magics init for rook+bishop goes from 200msecs to under 100msec. No functional change.
1 parent be77406 commit 35a0820

File tree

1 file changed

+12
-11
lines changed

1 file changed

+12
-11
lines changed

src/bitboard.cpp

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,9 @@ namespace {
249249
{ 728, 10316, 55013, 32803, 12281, 15100, 16645, 255 } };
250250

251251
Bitboard occupancy[4096], reference[4096], edges, b;
252-
int i, size;
252+
int age[4096], current = 0, i, size;
253+
254+
std::memset(age, 0, sizeof(age));
253255

254256
// attacks[s] is a pointer to the beginning of the attacks table for square 's'
255257
attacks[SQ_A1] = table;
@@ -298,22 +300,21 @@ namespace {
298300
magics[s] = rng.sparse_rand<Bitboard>();
299301
while (popcount<Max15>((magics[s] * masks[s]) >> 56) < 6);
300302

301-
std::memset(attacks[s], 0, size * sizeof(Bitboard));
302-
303303
// A good magic must map every possible occupancy to an index that
304304
// looks up the correct sliding attack in the attacks[s] database.
305305
// Note that we build up the database for square 's' as a side
306306
// effect of verifying the magic.
307-
for (i = 0; i < size; ++i)
307+
for (++current, i = 0; i < size; ++i)
308308
{
309-
Bitboard& attack = attacks[s][index(s, occupancy[i])];
310-
311-
if (attack && attack != reference[i])
309+
unsigned idx = index(s, occupancy[i]);
310+
311+
if (age[idx] < current)
312+
{
313+
age[idx] = current;
314+
attacks[s][idx] = reference[i];
315+
}
316+
else if (attacks[s][idx] != reference[i])
312317
break;
313-
314-
assert(reference[i]);
315-
316-
attack = reference[i];
317318
}
318319
} while (i < size);
319320
}

0 commit comments

Comments
 (0)