Merge bitcoin/bitcoin#34023: Optimized SFL cluster linearization

c2fcf250697325636218225d578c3844ab9ca633 clusterlin: inline GetReachable into Deactivate (optimization) (Pieter Wuille)
d90f98ab4aaaa6d524d8a2ab9fb3a8ba162ebb00 clusterlin: inline UpdateChunk into (De)Activate (optimization) (Pieter Wuille)
b684f954bbfcd9a18c05110b1124276554ba072e clusterlin: unidirectional MakeTopological initially (optimization) (Pieter Wuille)
1daa600c1ca82d16dd1661292949e56b4c4c6d94 clusterlin: track suboptimal chunks (optimization) (Pieter Wuille)
63b06d5523f1da37f76dc1f8b659959a127975f3 clusterlin: keep track of active children (optimization) (Pieter Wuille)
ae16485aa94dc745556615d569914b75ea855f02 clusterlin: special-case self-merges (optimization) (Pieter Wuille)
3221f1a074e7b313e97f969d11ff8a13a1dc5aa6 clusterlin: make MergeSequence take SetIdx (simplification) (Pieter Wuille)
7194de3f7c5324a6e719ed25ef292d162b4f5d88 clusterlin: precompute reachable sets (optimization) (Pieter Wuille)
6f898dbb8bfad68b3c2168471ced211222d6f7f3 clusterlin: simplify PickMergeCandidate (optimization) (Pieter Wuille)
dcf458ffb99c57c31c5c53e001c98fc1a8baadec clusterlin: split up OptimizeStep (refactor) (Pieter Wuille)
cbd684a4713dbe1adc77986e5924867f0e22fb6a clusterlin: abstract out functions from MergeStep (refactor) (Pieter Wuille)
b75574a6531ebe1f4077482705ad9e2db0ed3438 clusterlin: improve TxData::dep_top_idx type (optimization) (Pieter Wuille)
73cbd15d457221e2e896549a32df7f5a59a9df5c clusterlin: get rid of DepData (optimization) (Pieter Wuille)
7c6f63a8a9dc7e3d168dcb023f55936cd47ccf0b clusterlin: pool SetInfos (preparation) (Pieter Wuille)
20e2f3e96df31ffd32f0752e28d90de30942f5ed scripted-diff: rename _rep -> _idx in SFL (Pieter Wuille)
268fcb6a53ec034ec12a9c2cbaceca677664962b clusterlin: add more Assumes and sanity checks (tests) (Pieter Wuille)
d69c9f56ea96e333dbf2f5b4b4e63685147fbc72 clusterlin: count chunk deps without loop (optimization) (Pieter Wuille)
f66fa69ce008e512af8d7cc6b22f0b3a0a080b2c clusterlin: split tx/chunk dep counting (preparation) (Pieter Wuille)
900e45977889f9a189036f7b0e562f8e404c7190 clusterlin: avoid depgraph argument in SanityCheck (cleanup) (Pieter Wuille)
666b37970f1566b7b369c7c5f840099fa6eda800 clusterlin: fix type to count dependencies (Pieter Wuille)

Pull request description:

  Follow-up to #32545, part of #30289.

  This contains many of the optimizations that were originally part of #32545 itself.

  Here is a list of commits and the geometric average of the benchmark timings. Note that these aren't worst cases, but because of the nature of the optimizations here, I do expect them to apply roughly equally to all kinds of clusters. In other words, the relative improvement shown by these numbers should be representative:

  | commit title | ns per optimal linearization |
  |:--|--:|
  | clusterlin: split tx/chunk dep counting (preparation) | 24,760.30 |
  | clusterlin: count chunk deps without loop (optimization) | 24,677.64 |
  | scripted-diff: rename _rep -> _idx in SFL | 24,640.08 |
  | clusterlin: get rid of DepData, reuse sets (optimization) | 24,389.01 |
  | clusterlin: improve TxData::dep_top_idx type (optimization) | 22,578.58 |
  | clusterlin: abstract out functions from MergeStep (refactor) | 22,577.15 |
  | clusterlin: split up OptimizeStep (refactor) | 22,981.11 |
  | clusterlin: simplify PickMergeCandidate (optimization) | 22,018.63 |
  | clusterlin: precompute reachable sets (optimization) | 21,194.91 |
  | clusterlin: make MergeSequence take SetIdx (simplification) | 21,135.60 |
  | clusterlin: special-case self-merges (optimization) | 20,588.13 |
  | clusterlin: keep track of active children (optimization) | 13,911.22 |
  | clusterlin: track suboptimal chunks (optimization) | 13,629.42 |
  | clusterlin: unidirectional MakeTopological initially (optimization) | 12,796.57 |
  | clusterlin: inline UpdateChunk into (De)Activate (optimization) | 12,706.35 |
  | clusterlin: inline GetReachable into Deactivate (optimization) | 12,525.66 |

  And to show that they apply to all clusters roughly similarly:

  <img width="1239" height="640" alt="output(1)" src="https://github.com/user-attachments/assets/edd73937-3f87-4582-b2b9-eaed7e6ff352" />

ACKs for top commit:
  instagibbs:
    reACK  c2fcf250697325636218225d578c3844ab9ca633
  ajtowns:
    reACK c2fcf250697325636218225d578c3844ab9ca633

Tree-SHA512: e8920f7952a6681b4c1d70c864bd0e9784127ae4fd7c740be3e24a473f72e83544d2293066ed9b3e685b755febd6bbbc6c7da0c9b6ef3699b05eaa8d5bc073a0
This commit is contained in:
merge-script 2026-02-18 09:56:08 +00:00
commit 59e10a5463
No known key found for this signature in database
GPG Key ID: 2EEB9F5CC09526C1
3 changed files with 580 additions and 503 deletions

File diff suppressed because it is too large Load Diff

View File

@ -919,7 +919,7 @@ FUZZ_TARGET(clusterlin_sfl)
if (rng.randbits(4) == 0) {
// Perform sanity checks from time to time (too computationally expensive to do after
// every step).
sfl.SanityCheck(depgraph);
sfl.SanityCheck();
}
auto diagram = sfl.GetDiagram();
if (rng.randbits(4) == 0) {

View File

@ -402,14 +402,14 @@ inline uint64_t MaxOptimalLinearizationIters(DepGraphIndex cluster_count)
// *some* reasonable cost bound, optimal linearizations are always found.
static constexpr uint64_t ITERS[65] = {
0,
0, 4, 10, 34, 76, 118, 184, 225,
320, 376, 464, 573, 830, 868, 1019, 1468,
1375, 1785, 1880, 1854, 2551, 2559, 4336, 4784,
5547, 5807, 6157, 6075, 6961, 7403, 7756, 8001,
8041, 7579, 8483, 10077, 9015, 9388, 9626, 12371,
12847, 12102, 15173, 15800, 20319, 22190, 23183, 24361,
24909, 19225, 27419, 23789, 25909, 21993, 25596, 24130,
26349, 31823, 31855, 31250, 32688, 34825, 41710, 45478
0, 4, 10, 34, 76, 156, 229, 380,
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.