Skip to content

Commit

Permalink
clusterlin: only start/use search when enough iterations left
Browse files Browse the repository at this point in the history
  • Loading branch information
sipa authored and glozow committed Aug 6, 2024
1 parent 08f9f2f commit ad369cf
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 7 deletions.
37 changes: 30 additions & 7 deletions src/cluster_linearize.h
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,12 @@ class AncestorCandidateFinder
return m_todo.None();
}

/** Count the number of remaining unlinearized transactions. */
ClusterIndex NumRemaining() const noexcept
{
return m_todo.Count();
}

/** Find the best (highest-feerate, smallest among those in case of a tie) ancestor set
* among the remaining transactions. Requires !AllDone().
*
Expand Down Expand Up @@ -971,10 +977,18 @@ std::pair<std::vector<ClusterIndex>, bool> Linearize(const DepGraph<SetType>& de
std::vector<ClusterIndex> linearization;

AncestorCandidateFinder anc_finder(depgraph);
SearchCandidateFinder src_finder(depgraph, rng_seed);
std::optional<SearchCandidateFinder<SetType>> src_finder;
linearization.reserve(depgraph.TxCount());
bool optimal = true;

// Treat the initialization of SearchCandidateFinder as taking N^2/64 (rounded up) iterations.
// If we don't have that many, don't start it.
uint64_t start_iterations = (uint64_t{depgraph.TxCount()} * depgraph.TxCount() + 63) / 64;
if (iterations_left > start_iterations) {
iterations_left -= start_iterations;
src_finder.emplace(depgraph, rng_seed);
}

/** Chunking of what remains of the old linearization. */
LinearizationChunking old_chunking(depgraph, old_linearization);

Expand All @@ -987,12 +1001,21 @@ std::pair<std::vector<ClusterIndex>, bool> Linearize(const DepGraph<SetType>& de
auto best = anc_finder.FindCandidateSet();
if (!best_prefix.feerate.IsEmpty() && best_prefix.feerate >= best.feerate) best = best_prefix;

// Invoke bounded search to update best, with up to half of our remaining iterations as
// limit.
uint64_t max_iterations_now = (iterations_left + 1) / 2;
uint64_t iterations_done_now = 0;
std::tie(best, iterations_done_now) = src_finder.FindCandidateSet(max_iterations_now, best);
iterations_left -= iterations_done_now;
uint64_t max_iterations_now = 0;
if (src_finder) {
// Treat the invocation of SearchCandidateFinder::FindCandidateSet() as costing N/4
// iterations (rounded up).
uint64_t base_iterations = (anc_finder.NumRemaining() + 3) / 4;
if (iterations_left > base_iterations) {
// Invoke bounded search to update best, with up to half of our remaining
// iterations as limit.
iterations_left -= base_iterations;
max_iterations_now = (iterations_left + 1) / 2;
std::tie(best, iterations_done_now) = src_finder->FindCandidateSet(max_iterations_now, best);
iterations_left -= iterations_done_now;
}
}

if (iterations_done_now == max_iterations_now) {
optimal = false;
Expand All @@ -1010,7 +1033,7 @@ std::pair<std::vector<ClusterIndex>, bool> Linearize(const DepGraph<SetType>& de
// Update state to reflect best is no longer to be linearized.
anc_finder.MarkDone(best.transactions);
if (anc_finder.AllDone()) break;
src_finder.MarkDone(best.transactions);
if (src_finder) src_finder->MarkDone(best.transactions);
if (old_chunking.NumChunksLeft() > 0) {
old_chunking.MarkDone(best.transactions);
}
Expand Down
4 changes: 4 additions & 0 deletions src/test/fuzz/cluster_linearize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,7 @@ FUZZ_TARGET(clusterlin_ancestor_finder)
while (todo.Any()) {
// Call the ancestor finder's FindCandidateSet for what remains of the graph.
assert(!anc_finder.AllDone());
assert(todo.Count() == anc_finder.NumRemaining());
auto best_anc = anc_finder.FindCandidateSet();
// Sanity check the result.
assert(best_anc.transactions.Any());
Expand Down Expand Up @@ -489,6 +490,7 @@ FUZZ_TARGET(clusterlin_ancestor_finder)
anc_finder.MarkDone(del_set);
}
assert(anc_finder.AllDone());
assert(anc_finder.NumRemaining() == 0);
}

static constexpr auto MAX_SIMPLE_ITERATIONS = 300000;
Expand Down Expand Up @@ -523,6 +525,7 @@ FUZZ_TARGET(clusterlin_search_finder)
assert(!smp_finder.AllDone());
assert(!exh_finder.AllDone());
assert(!anc_finder.AllDone());
assert(anc_finder.NumRemaining() == todo.Count());

// For each iteration, read an iteration count limit from the fuzz input.
uint64_t max_iterations = 1;
Expand Down Expand Up @@ -605,6 +608,7 @@ FUZZ_TARGET(clusterlin_search_finder)
assert(smp_finder.AllDone());
assert(exh_finder.AllDone());
assert(anc_finder.AllDone());
assert(anc_finder.NumRemaining() == 0);
}

FUZZ_TARGET(clusterlin_linearization_chunking)
Expand Down

0 comments on commit ad369cf

Please sign in to comment.