Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions library/src/ab_search.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,13 @@ auto apply_ab_tt_lookup(
limit, lowerFlag);
TIMER_END(TIMER_NO_LOOKUP, depth);

// Instrumentation: per-thread TT lookup/hit counters
if (thrp) {
++thrp->tt_lookup_count;
if (cardsP)
++thrp->tt_hit_count;
}
Comment thread
zzcgumn marked this conversation as resolved.

if (!cardsP)
return false;

Expand Down
60 changes: 60 additions & 0 deletions library/src/solver_if.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
See LICENSE and README.
*/

#include <cstdlib>
#include <cstdio>
#include <cinttypes>
#include <ab_search.hpp>
#include <dump.hpp>
#include <init.hpp>
Expand Down Expand Up @@ -170,6 +173,11 @@ auto solve_board_internal(
if (ret != RETURN_NO_FAULT)
return ret;

// Reset per-solve TT stats here so the SOLVER_DONE report reflects
// this board even when the last-trick early exit below is taken.
thrp->tt_lookup_count = 0;
thrp->tt_hit_count = 0;
if (auto* tt = ctx.trans_table()) tt->reset_op_stats();

// ----------------------------------------------------------
// Last trick, easy to solve.
Expand Down Expand Up @@ -670,6 +678,30 @@ auto solve_board_internal(
futp->nodes = ctx.search().trick_nodes();
}

// Print TT stats if requested
if (auto* env = std::getenv("DDS_PRINT_TT_STATS"); env && env[0] == '1' && env[1] == '\0') {
ThreadData* thrp_ptr = ctx.thread_ptr();
if (thrp_ptr) {
double hit_rate = thrp_ptr->tt_lookup_count > 0 ?
100.0 * (double)thrp_ptr->tt_hit_count /
(double)thrp_ptr->tt_lookup_count : 0.0;
std::fprintf(stderr,
"DDS_TT_STATS: lookups=%" PRIu64 " hits=%" PRIu64 " hit_rate=%.2f%%\n",
thrp_ptr->tt_lookup_count,
thrp_ptr->tt_hit_count,
hit_rate);
if (auto* tt = ctx.trans_table()) {
int adds, overwrites, harvests;
tt->get_op_stats(adds, overwrites, harvests);
double ow_rate = adds > 0 ?
100.0 * (double)overwrites / (double)adds : 0.0;
std::fprintf(stderr,
"DDS_TT_STATS: adds=%d overwrites=%d overwrite_rate=%.2f%% harvests=%d\n",
adds, overwrites, ow_rate, harvests);
}
}
}

#ifdef DDS_MEMORY_LEAKS_WIN32
_CrtDumpMemoryLeaks();
#endif
Expand Down Expand Up @@ -721,6 +753,10 @@ auto solve_same_board(
thrp->ABStats.Reset();
thrp->ABStats.ResetCum();
#endif
// Reset per-solve TT stats (keeps warm TT, resets counters only)
thrp->tt_lookup_count = 0;
thrp->tt_hit_count = 0;
if (auto* tt = ctx.trans_table()) tt->reset_op_stats();

#ifdef DDS_TOP_LEVEL
{
Expand Down Expand Up @@ -811,6 +847,30 @@ auto solve_same_board(
futp->nodes = ctx.search().trick_nodes();
}

// Print TT stats if requested
if (auto* env = std::getenv("DDS_PRINT_TT_STATS"); env && env[0] == '1' && env[1] == '\0') {
Comment thread
zzcgumn marked this conversation as resolved.
ThreadData* thrp_ptr = ctx.thread_ptr();
if (thrp_ptr) {
double hit_rate = thrp_ptr->tt_lookup_count > 0 ?
100.0 * (double)thrp_ptr->tt_hit_count /
(double)thrp_ptr->tt_lookup_count : 0.0;
std::fprintf(stderr,
"DDS_TT_STATS: lookups=%" PRIu64 " hits=%" PRIu64 " hit_rate=%.2f%%\n",
thrp_ptr->tt_lookup_count,
thrp_ptr->tt_hit_count,
hit_rate);
if (auto* tt = ctx.trans_table()) {
int adds, overwrites, harvests;
tt->get_op_stats(adds, overwrites, harvests);
double ow_rate = adds > 0 ?
100.0 * (double)overwrites / (double)adds : 0.0;
std::fprintf(stderr,
"DDS_TT_STATS: adds=%d overwrites=%d overwrite_rate=%.2f%% harvests=%d\n",
adds, overwrites, ow_rate, harvests);
}
}
}

#ifdef DDS_MEMORY_LEAKS_WIN32
_CrtDumpMemoryLeaks();
#endif
Expand Down
7 changes: 7 additions & 0 deletions library/src/system/thread_data.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <api/dds_data_types.hpp>
#include <moves/moves.hpp>
#include <string>
#include <cstdint>

#ifdef DDS_AB_STATS
#include "ab_stats.hpp"
Expand Down Expand Up @@ -61,6 +62,12 @@ struct ThreadData
double memUsed;
int nodes;
int trickNodes;
// TT instrumentation (per-context, single-threaded).
// tt_lookup_count: total TT probe calls on the AB hot path.
// tt_hit_count: probes that returned a cached result (higher is better).
// hit_rate = tt_hit_count / tt_lookup_count; target: maximize.
uint64_t tt_lookup_count = 0;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to see comments for these two.

uint64_t tt_hit_count = 0;

// Constant for a given hand.
// 960 KB
Expand Down
6 changes: 6 additions & 0 deletions library/src/trans_table/trans_table.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,12 @@ class TransTable
/// \brief Print suit statistics for all tricks and hands.
virtual auto print_all_suit_stats(std::ofstream& fout) const -> void = 0;

/// \brief Get add/overwrite/harvest counters for instrumentation.
virtual auto get_op_stats(int& adds, int& overwrites, int& harvests) const -> void = 0;

/// \brief Reset add/overwrite/harvest counters for per-solve stats.
virtual auto reset_op_stats() -> void = 0;

/// \brief Print summary suit statistics.
virtual auto print_summary_suit_stats(std::ofstream& fout) const -> void = 0;

Expand Down
7 changes: 6 additions & 1 deletion library/src/trans_table/trans_table_l.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ TransTableL::TransTableL()
pages_maximum_ = 0;
harvest_trick_ = 0;
harvest_hand_ = 0;
page_stats_ = PageStats{0,0,0,0,0};
page_stats_ = PageStats{0,0,0,0,0,0,0};
timestamp_ = 0;
pool_ = nullptr;
next_block_ = nullptr;
Expand Down Expand Up @@ -470,6 +470,8 @@ auto TransTableL::return_all_memory() -> void
page_stats_.num_frees_ = 0;
page_stats_.num_harvests_ = 0;
page_stats_.last_current_ = 0;
page_stats_.num_adds_ = 0;
page_stats_.num_overwrites_ = 0;

TransTableL::release_tt();

Expand Down Expand Up @@ -931,7 +933,10 @@ auto TransTableL::create_or_update(
return;
}

// Instrumentation: count new insertions and overwrites
page_stats_.num_adds_++;
if (n == BlocksPerEntry) {
page_stats_.num_overwrites_++;
if (bp->next_write_no_ >= BlocksPerEntry)
bp->next_write_no_ = 0;
}
Comment thread
wopdevries marked this conversation as resolved.
Expand Down
16 changes: 16 additions & 0 deletions library/src/trans_table/trans_table_l.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,8 @@ class TransTableL: public TransTable
int num_frees_; ///< Total deallocations
int num_harvests_; ///< Total harvest operations
int last_current_; ///< Last current page number
int num_adds_; ///< Total new entries inserted
int num_overwrites_; ///< Insertions that overwrote existing entries
};

/// \brief Harvested blocks saved for potential reuse (16 bytes).
Expand Down Expand Up @@ -460,6 +462,20 @@ class TransTableL: public TransTable
/// \param fout Output stream
auto print_all_suit_stats(std::ofstream& fout) const -> void override;

/// \brief Reset per-solve operation counters (adds, overwrites, harvests).
auto reset_op_stats() -> void override
{
page_stats_.num_adds_ = 0;
page_stats_.num_overwrites_ = 0;
page_stats_.num_harvests_ = 0;
}
/// \brief Get per-solve operation counters for instrumentation.
auto get_op_stats(int& adds, int& overwrites, int& harvests) const -> void override
{
adds = page_stats_.num_adds_;
overwrites = page_stats_.num_overwrites_;
harvests = page_stats_.num_harvests_;
}
/// \brief Print summary suit statistics.
///
/// \param fout Output stream
Expand Down
2 changes: 2 additions & 0 deletions library/src/trans_table/trans_table_p.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -647,6 +647,7 @@ auto TransTableP::add(
}
if (stored_weight == weight && same_pattern(stored.key, pattern)) {
tighten(stored.cards, cards, flag);
++num_tightens_;
return;
}
}
Expand All @@ -662,6 +663,7 @@ auto TransTableP::add(
++tree.bucket_end[b];
}
++node_count_;
++num_adds_;
}


Expand Down
15 changes: 15 additions & 0 deletions library/src/trans_table/trans_table_p.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,21 @@ class TransTableP : public TransTable
auto print_all_suits(std::ofstream& fout) const -> void override;
auto print_suit_stats(std::ofstream& fout, int trick, int hand) const -> void override;
auto print_all_suit_stats(std::ofstream& fout) const -> void override;
auto reset_op_stats() -> void override
{
num_adds_ = 0;
num_tightens_ = 0;
}
auto get_op_stats(int& adds, int& overwrites, int& harvests) const -> void override
{
adds = num_adds_;
overwrites = 0; // PatternTT has no eviction; use tightens() for in-place updates
harvests = 0; // TransTableP has no harvest mechanism
Comment thread
zzcgumn marked this conversation as resolved.
}
// Instrumentation counters
mutable int num_adds_ = 0;
mutable int num_tightens_ = 0; ///< Duplicate-pattern tighten updates (not replacement churn)
Comment on lines +106 to +108

auto print_summary_suit_stats(std::ofstream& fout) const -> void override;
auto print_entries_dist(
std::ofstream& fout, int trick, int hand, const int hand_dist[]) const -> void override;
Expand Down
9 changes: 9 additions & 0 deletions library/src/trans_table/trans_table_s.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,15 @@ class TransTableS: public TransTable
auto print_all_suit_stats(std::ofstream& /*fout*/) const -> void override
{
}
auto reset_op_stats() -> void override
{
}
auto get_op_stats(int& adds, int& overwrites, int& harvests) const -> void override
{
adds = 0;
overwrites = 0;
harvests = 0; // TransTableS not instrumented
}
auto print_summary_suit_stats(std::ofstream& /*fout*/) const -> void override
{
}
Expand Down
9 changes: 9 additions & 0 deletions library/tests/trans_table/trans_table_base_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,15 @@ class TransTableBaseTest : public ::testing::Test
MockTransTable() : TransTable() {}

~MockTransTable() override = default;
auto get_op_stats(int& adds, int& overwrites, int& harvests) const -> void override
{
adds = 0;
overwrites = 0;
harvests = 0;
}
auto reset_op_stats() -> void override
{
}

void init(const int handLookup[][15]) override
{
Expand Down