clusterlin: unidirectional MakeTopological initially (optimization)

It suffices to initially only attempt one direction of merges in
MakeTopological(), and only try both directions on chunks that are the
result of other merges.
This commit is contained in:
Pieter Wuille
2025-10-15 17:59:09 -04:00
committed by Pieter Wuille
parent 1daa600c1c
commit b684f954bb
2 changed files with 23 additions and 7 deletions

View File

@@ -1129,6 +1129,16 @@ public:
void MakeTopological() noexcept
{
Assume(m_suboptimal_chunks.empty());
/** What direction to initially merge chunks in; one of the two directions is enough. This
* is sufficient because if a non-topological inactive dependency exists between two
* chunks, at least one of the two chunks will eventually be processed in a direction that
* discovers it - either the lower chunk tries upward, or the upper chunk tries downward.
* Chunks that are the result of the merging are always tried in both directions. */
unsigned init_dir = m_rng.randbool();
/** Which chunks are the result of merging, and thus need merge attempts in both
* directions. */
SetType merged_chunks;
// Mark chunks as suboptimal.
m_suboptimal_idxs = m_chunk_idxs;
for (auto chunk_idx : m_chunk_idxs) {
m_suboptimal_chunks.emplace_back(chunk_idx);
@@ -1147,9 +1157,12 @@ public:
// If what was popped is not currently a chunk, continue. This may
// happen when it was merged with something else since being added.
if (!m_chunk_idxs[chunk_idx]) continue;
/** What direction(s) to attempt merging in. 1=up, 2=down, 3=both. */
unsigned direction = merged_chunks[chunk_idx] ? 3 : init_dir + 1;
int flip = m_rng.randbool();
for (int i = 0; i < 2; ++i) {
if (i ^ flip) {
if (!(direction & 1)) continue;
// Attempt to merge the chunk upwards.
auto result_up = MergeStep<false>(chunk_idx);
if (result_up != INVALID_SET_IDX) {
@@ -1157,9 +1170,11 @@ public:
m_suboptimal_idxs.Set(result_up);
m_suboptimal_chunks.push_back(result_up);
}
merged_chunks.Set(result_up);
break;
}
} else {
if (!(direction & 2)) continue;
// Attempt to merge the chunk downwards.
auto result_down = MergeStep<true>(chunk_idx);
if (result_down != INVALID_SET_IDX) {
@@ -1167,6 +1182,7 @@ public:
m_suboptimal_idxs.Set(result_down);
m_suboptimal_chunks.push_back(result_down);
}
merged_chunks.Set(result_down);
break;
}
}

View File

@@ -403,13 +403,13 @@ inline uint64_t MaxOptimalLinearizationIters(DepGraphIndex cluster_count)
static constexpr uint64_t ITERS[65] = {
0,
0, 4, 10, 34, 76, 156, 229, 380,
432, 517, 678, 896, 1037, 1366, 1464, 1792,
2060, 2542, 3068, 3116, 4029, 3467, 5324, 5512,
6481, 7161, 7441, 8183, 8843, 9353, 11104, 11269,
11791, 11871, 13367, 14259, 14229, 12397, 13581, 18152,
18737, 16581, 23217, 24044, 29597, 29030, 34069, 34594,
33630, 26227, 34471, 38815, 40814, 31182, 40305, 34019,
36582, 55659, 39994, 41277, 42365, 52822, 59733, 67035
441, 517, 678, 933, 1037, 1366, 1464, 1711,
2111, 2542, 3068, 3116, 4029, 3467, 5324, 5402,
6481, 7161, 7441, 8183, 8843, 9353, 11104, 11455,
11791, 12570, 13480, 14259, 14525, 12426, 14477, 20201,
18737, 16581, 23622, 28486, 30652, 33021, 32942, 32745,
34046, 26227, 34662, 38019, 40814, 31113, 41448, 33968,
35024, 59207, 42872, 41277, 42365, 51833, 63410, 67035
};
assert(cluster_count < std::size(ITERS));
// Multiply the table number by two, to account for the fact that they are not absolutes.