Symbolic has several transposition table classes, each of them having the same base class which contains member variables common to all derived classes.
Code: Select all
class TranBase
{
public:
TranBase(const TtId table, const ui log2count);
TranBase(const TtId table, const double frac);
#if (EnableTranStats)
void IncrMatch(void) {ctspinlock.Lock(); ctmatch++; ctspinlock.Unlock();}
void IncrProbe(void) {ctspinlock.Lock(); ctprobe++; ctspinlock.Unlock();}
void IncrStash(void) {ctspinlock.Lock(); ctstash++; ctspinlock.Unlock();}
void IncrUsage(void) {ctspinlock.Lock(); ctusage++; ctspinlock.Unlock();}
#else
void IncrMatch(void) {}
void IncrProbe(void) {}
void IncrStash(void) {}
void IncrUsage(void) {}
#endif
void LsbReporter(const Hash& hash0, const Hash& hash1);
std::string EncodeStats(void) const;
std::string Encode(void) const;
protected:
static const std::string basenames[TtIdLen];
static const size_t itemsizes[TtIdLen];
void SetUpFromLog2(const TtId table, const ui log2count);
void SetUpFromFrac(const TtId table, const double frac);
ui CalcSlice(const usize offset) const {return ((ui) (offset >> sliceshift)) & slicemask;}
void FastReset(void);
TtId ttid;
std::string name;
ui log2entrycount; // Log2 of entry count
size_t entrysize; // Size of a single entry
size_t tablesize; // Size of the entire storage region
usize entrycount; // Number of entries
usize addrmask; // Address generation mask
ui sliceshift; // Slice shift bit count
usize slicemask; // Slice index generation mask
ui64 ctmatch; // Count of probe matches
ui64 ctprobe; // Count of probe calls
ui64 ctstash; // Count of stash calls
ui64 ctusage; // Count of used entries
SpinLock ctspinlock; // Count access spinlock
ui lsbhwm; // LSB match high water mark
SpinLock lsbspinlock; // Spinlock for high watermark access
void *storeptr; // Pointer to allocated storage region
SpinLock SLSliceVec[SLSliceLen]; // Regional access spinlocks
};
When a table is created, its constructor resets these members. They stay that way unless the compile time symbol EnableTranStats is set, in which case the counter increment routines are called when appropriate. The member method EncodeStats() presents these in text format when called.
These are handy numbers to have. But their generation does eat some time. How much time? An empirical answer follows.
The task used for the experiment is the calculation of the value of perft(9) of the initial array, which is 2,439,530,234,167. This was done by running four hyperthreads on a dual core 64 bit CPU with a transposition table containing 268,435,456 (2^28) elements with 128 bit signatures.
First, without instrumentation:
Code: Select all
[] pctran 9
TT: PETBase: ItemCount: 268,435,456 (2^28) ItemSize: 24 B TableSize: 6 GiB
Count: 2,439,530,234,167 Pt: 32:20.992 Wt: 8:27.289 U: 3.8262 4.80895 GHz 207.946 ps
Total: two trillion four hundred thirty-nine billion five hundred thirty million two hundred thirty-four thousand one hundred sixty-seven
Code: Select all
[] pctran 9
TT: PETBase: ItemCount: 268,435,456 (2^28) ItemSize: 24 B TableSize: 6 GiB
TT: PETBase: items: 268,435,456 probe: 280,394,218 match: 169,624,952 stash: 111,793,594 usage: 99,677,863 load: 0.371329
Count: 2,439,530,234,167 Pt: 32:46.044 Wt: 8:33.844 U: 3.82615 4.74761 GHz 210.632 ps
Total: two trillion four hundred thirty-nine billion five hundred thirty million two hundred thirty-four thousand one hundred sixty-seven
So now you know.