optimization: bulk reads(32%)/writes(298%) in [undo]block [de]serialization, ~6% faster IBD #31551

pull l0rinc wants to merge 4 commits into bitcoin:master from l0rinc:l0rinc/bulk-block-read-write changing 5 files +109 −41
  1. l0rinc commented at 2:34 pm on December 21, 2024: contributor

    Currently, obfuscation operations are performed byte-by-byte during serialization. Buffering the reads allows batching these operations (implemented in #31144) and improves file access efficiency by reducing fread calls and associated locking overhead. But even without that change, batching reads/writes (instead of just relying on the OS buffering them) has a measurable speed increase for block reading/writing. For writes, buffering enables batched obfuscations directly on the internal buffer (avoiding the need to copy input spans for obfuscation). Also, for writes the Xor key offsets are now calculated based on the file position, and the batched obfuscation is applied before writing to disk only.


    Microbenchmarks for [Read|Save]BlockBench show a ~32%/298% speedup with Clang, and ~24%/31% with GCC (the followup XOR batching improves these further):

    Before:

    ns/op op/s err% total benchmark
    2,289,743.62 436.73 0.3% 11.03 ReadBlockBench
    5,267,613.94 189.84 1.0% 11.05 SaveBlockBench

    After:

    ns/op op/s err% total benchmark
    1,724,703.14 579.81 0.4% 11.06 ReadBlockBench
    1,767,367.40 565.81 1.6% 10.86 SaveBlockBench

    Before:

    ns/op op/s err% ins/op cyc/op IPC bra/op miss% total benchmark
    7,786,309.20 128.43 0.0% 70,832,812.80 23,803,523.16 2.976 5,073,002.56 0.4% 10.72 ReadBlockBench
    4,128,530.90 242.22 3.8% 19,358,001.33 8,601,983.31 2.250 3,079,334.76 0.4% 10.64 SaveBlockBench

    After:

    ns/op op/s err% ins/op cyc/op IPC bra/op miss% total benchmark
    6,272,557.28 159.42 0.0% 63,251,231.42 19,739,780.92 3.204 3,589,886.66 0.3% 10.57 ReadBlockBench
    3,130,556.05 319.43 4.7% 17,305,378.56 6,457,946.37 2.680 2,579,854.87 0.3% 10.83 SaveBlockBench

    2 full IBD runs against master (compiled with GCC where the gains seem more modest) for 870k blocks (seeded from real nodes) indicates a ~6% total speedup.

     0hyperfine --runs 2 --export-json /mnt/my_storage/ibd-xor-buffered.json --parameter-list COMMIT d73f37dda221835b5109ede1b84db2dc7c4b74a1,6853b2740851befffa3ca0b24d94212ed1e48d66 --prepare 'rm -rf /mnt/my_storage/BitcoinData/* && git checkout {COMMIT} && git clean -fxd && git reset --hard && cmake -B build -DCMAKE_BUILD_TYPE=Release -DBUILD_UTIL=OFF -DBUILD_TX=OFF -DBUILD_TESTS=OFF -DENABLE_WALLET=OFF -DINSTALL_MAN=OFF && cmake --build build -j$(nproc)' 'COMMIT={COMMIT} ./build/src/bitcoind -datadir=/mnt/my_storage/BitcoinData -stopatheight=870000 -printtoconsole=0'
     1
     2Benchmark 1: COMMIT=d73f37dda221835b5109ede1b84db2dc7c4b74a1 ./build/src/bitcoind -datadir=/mnt/my_storage/BitcoinData -stopatheight=870000 -printtoconsole=0
     3  Time (mean ± σ):     40216.674 s ± 113.132 s    [User: 51496.289 s, System: 3541.340 s]
     4  Range (min … max):   40136.678 s … 40296.671 s    2 runs
     5
     6Benchmark 2: COMMIT=6853b2740851befffa3ca0b24d94212ed1e48d66 ./build/src/bitcoind -datadir=/mnt/my_storage/BitcoinData -stopatheight=870000 -printtoconsole=0
     7  Time (mean ± σ):     37964.015 s ± 624.115 s    [User: 49086.037 s, System: 3375.072 s]
     8  Range (min … max):   37522.699 s … 38405.331 s    2 runs
     9
    10Summary
    11  COMMIT=6853b2740851befffa3ca0b24d94212ed1e48d66 ./build/src/bitcoind -datadir=/mnt/my_storage/BitcoinData -stopatheight=870000 -printtoconsole=0 ran
    12    1.06 ± 0.02 times faster than COMMIT=d73f37dda221835b5109ede1b84db2dc7c4b74a1 ./build/src/bitcoind -datadir=/mnt/my_storage/BitcoinData -stopatheight=870000 -printtoconsole=0
    

    And rerun the whole thing after rebasing (with 3 runs for stability, since this is an IBD with real nodes):

     0COMMITS="5acf12bafeb126f2190b3f401f95199e0eea90c9 0e9fb2ed330960c0e4cd36b077c64ac7d0f84240"; \
     1STOP_HEIGHT=880000; DBCACHE=30000; \
     2hyperfine \
     3--runs 3 \
     4--parameter-list COMMIT ${COMMITS/ /,} \
     5--prepare "rm -rf /mnt/my_storage/BitcoinData/* && git checkout {COMMIT} && git clean -fxd && git reset --hard && cmake -B build -DCMAKE_BUILD_TYPE=Release -DENABLE_WALLET=OFF -DCMAKE_C_COMPILER=$C_COMPILER -DCMAKE_CXX_COMPILER=$CXX_COMPILER && cmake --build build -j$(nproc) --target bitcoind && ./build/src/bitcoind -datadir=/mnt/my_storage/BitcoinData -stopatheight=1 -printtoconsole=0 || true" \
     6--cleanup "mv /mnt/my_storage/BitcoinData/debug.log /mnt/my_storage/logs/debug-{COMMIT}-$(date +%s).log" \
     7"COMMIT={COMMIT} ./build/src/bitcoind -datadir=/mnt/my_storage/BitcoinData -stopatheight=$STOP_HEIGHT -dbcache=$DBCACHE -printtoconsole=0"
     8
     9Benchmark 1: COMMIT=5acf12bafeb126f2190b3f401f95199e0eea90c9 ./build/src/bitcoind -datadir=/mnt/my_storage/BitcoinData -stopatheight=880000 -dbcache=30000 -printtoconsole=0
    10  Time (mean ± σ):     39757.551 s ± 258.042 s    [User: 52930.007 s, System: 2104.410 s]
    11  Range (min … max):   39469.858 s … 39968.556 s    3 runs
    12 
    13Benchmark 2: COMMIT=0e9fb2ed330960c0e4cd36b077c64ac7d0f84240 ./build/src/bitcoind -datadir=/mnt/my_storage/BitcoinData -stopatheight=880000 -dbcache=30000 -printtoconsole=0
    14  Time (mean ± σ):     37567.700 s ± 540.547 s    [User: 50713.745 s, System: 1904.750 s]
    15  Range (min … max):   37168.815 s … 38182.906 s    3 runs
    16 
    17Summary
    18  COMMIT=0e9fb2ed330960c0e4cd36b077c64ac7d0f84240 ./build/src/bitcoind -datadir=/mnt/my_storage/BitcoinData -stopatheight=880000 -dbcache=30000 -printtoconsole=0 ran
    19    1.06 ± 0.02 times faster than COMMIT=5acf12bafeb126f2190b3f401f95199e0eea90c9 ./build/src/bitcoind -datadir=/mnt/my_storage/BitcoinData -stopatheight=880000 -dbcache=30000 -printtoconsole=0
    

    Doin only reindex-chainstate runs (i.e. without writing [undo]blocks) until 880k with GCC results in a ~4% speedup:

     0COMMITS=5acf12bafeb126f2190b3f401f95199e0eea90c9,97b4a50c714c801e08bc02648a9c259f284069c2; 
     1STOP_HEIGHT=880000; DBCACHE=30000; \
     2hyperfine --runs 2 --parameter-list COMMIT $COMMITS \
     3--prepare "rm -rf /mnt/my_storage/BitcoinData/debug.log && git checkout {COMMIT} && git clean -fxd && git reset --hard && cmake -B build -DCMAKE_BUILD_TYPE=Release -DENABLE_WALLET=OFF && cmake --build build -j$(nproc) --target bitcoind && ./build/src/bitcoind -datadir=/mnt/my_storage/BitcoinData -stopatheight=$STOP_HEIGHT -dbcache=10000 -printtoconsole=0 || true" \
     4--cleanup "mv /mnt/my_storage/BitcoinData/debug.log /mnt/my_storage/logs/debug-{COMMIT}-$(date +%s).log" \
     5"COMMIT={COMMIT} ./build/src/bitcoind -datadir=/mnt/my_storage/BitcoinData -stopatheight=$STOP_HEIGHT -dbcache=$DBCACHE -printtoconsole=0 -reindex-chainstate -connect=0"
     6
     7Benchmark 1: COMMIT=5acf12bafeb126f2190b3f401f95199e0eea90c9 ./build/src/bitcoind -datadir=/mnt/my_storage/BitcoinData -stopatheight=880000 -dbcache=30000 -printtoconsole=0 -reindex-chainstate -connect=0
     8  Time (mean ± σ):     19907.833 s ± 44.135 s    [User: 41042.962 s, System: 867.501 s]
     9  Range (min … max):   19876.625 s … 19939.041 s    2 runs
    10
    11Benchmark 2: COMMIT=97b4a50c714c801e08bc02648a9c259f284069c2 ./build/src/bitcoind -datadir=/mnt/my_storage/BitcoinData -stopatheight=880000 -dbcache=30000 -printtoconsole=0 -reindex-chainstate -connect=0
    12  Time (mean ± σ):     19097.030 s ± 26.665 s    [User: 40017.301 s, System: 739.273 s]
    13  Range (min … max):   19078.174 s … 19115.885 s    2 runs
    14
    15Summary
    16  COMMIT=97b4a50c714c801e08bc02648a9c259f284069c2 ./build/src/bitcoind -datadir=/mnt/my_storage/BitcoinData -stopatheight=880000 -dbcache=30000 -printtoconsole=0 -reindex-chainstate -connect=0 ran
    17    1.04 ± 0.00 times faster than COMMIT=5acf12bafeb126f2190b3f401f95199e0eea90c9 ./build/src/bitcoind -datadir=/mnt/my_storage/BitcoinData -stopatheight=880000 -dbcache=30000 -printtoconsole=0 -reindex-chainstate -connect=0
    
  2. DrahtBot commented at 2:34 pm on December 21, 2024: contributor

    The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

    Code Coverage & Benchmarks

    For details see: https://corecheck.dev/bitcoin/bitcoin/pulls/31551.

    Reviews

    See the guideline for information on the review process. A summary of reviews will appear here.

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #31519 (refactor: Use std::span over Span by maflcko)
    • #31144 (optimization: batch XOR operations 12% faster IBD by l0rinc)

    If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

  3. l0rinc force-pushed on Dec 21, 2024
  4. l0rinc renamed this:
    optimization: bulk reads(27%)/writes(290%) in [undo]block [de]serialization
    optimization: bulk reads(27%)/writes(290%) in [undo]block [de]serialization, 6% faster IBD
    on Dec 21, 2024
  5. l0rinc force-pushed on Dec 21, 2024
  6. DrahtBot added the label Needs rebase on Jan 22, 2025
  7. l0rinc force-pushed on Jan 22, 2025
  8. DrahtBot removed the label Needs rebase on Jan 22, 2025
  9. l0rinc force-pushed on Jan 22, 2025
  10. l0rinc marked this as ready for review on Jan 22, 2025
  11. l0rinc force-pushed on Jan 22, 2025
  12. DrahtBot commented at 11:14 pm on January 22, 2025: contributor

    🚧 At least one of the CI tasks failed. Debug: https://github.com/bitcoin/bitcoin/runs/36027778098

    Try to run the tests locally, according to the documentation. However, a CI failure may still happen due to a number of reasons, for example:

    • Possibly due to a silent merge conflict (the changes in this pull request being incompatible with the current code in the target branch). If so, make sure to rebase on the latest commit of the target branch.

    • A sanitizer issue, which can only be found by compiling with the sanitizer and running the affected test.

    • An intermittent issue.

    Leave a comment here, if you need help tracking down a confusing failure.

  13. DrahtBot added the label CI failed on Jan 22, 2025
  14. l0rinc force-pushed on Jan 22, 2025
  15. DrahtBot removed the label CI failed on Jan 23, 2025
  16. l0rinc marked this as a draft on Jan 23, 2025
  17. l0rinc marked this as ready for review on Jan 23, 2025
  18. in src/node/blockstorage.cpp:1029 in 0e9fb2ed33 outdated
    1026+
    1027     // Open history file to read
    1028     AutoFile filein{OpenBlockFile(pos, true)};
    1029     if (filein.IsNull()) {
    1030-        LogError("%s: OpenBlockFile failed for %s\n", __func__, pos.ToString());
    1031+        LogError("OpenBlockFile failed for %s", pos.ToString());
    


    maflcko commented at 1:58 pm on January 24, 2025:

    I am not a fan of mixing logging changes into a commit that does something completely different (claimed optimization).

    Also, not everyone has srclocation logging enabled, so the log strings should still be unique.

    Looks like the prior pull did something similar and now there are two LogError("OpenUndoFile failed"); in two different contexts. So when removing the __func__, it would be good to add back any context that was removed (i.e. whether it was opened for reading or writing).


    l0rinc commented at 2:30 pm on January 24, 2025:
    Thank you, excellent observation. I have separated the comment updates to a final commit and fixed the previous PR’s comments as well. Done
  19. l0rinc force-pushed on Jan 24, 2025
  20. in src/node/blockstorage.cpp:690 in f8b1b218b4 outdated
    688-    HashVerifier verifier{filein}; // Use HashVerifier as reserializing may lose data, c.f. commit d342424301013ec47dc146a4beb49d5c9319d80a
    689     try {
    690+        // Read block
    691+        filein >> undo_size;
    692+        if (undo_size > MAX_SIZE) {
    693+            LogError("%s: Refusing to read undo data of size: %d", __func__, undo_size);
    


    maflcko commented at 3:42 pm on January 24, 2025:
    nit in f8b1b218b4f8533128b337168b6769e2e4c30c02: I think for new logs, __func__ is not needed. Refusing to read undo data of size looks unique as well.

    l0rinc commented at 4:26 pm on January 24, 2025:
    Done
  21. in src/node/blockstorage.cpp:696 in f8b1b218b4 outdated
    712         LogError("%s: Deserialize or I/O error - %s at %s\n", __func__, e.what(), pos.ToString());
    713         return false;
    714     }
    715 
    716-    // Verify checksum
    717-    if (hashChecksum != verifier.GetHash()) {
    


    maflcko commented at 3:46 pm on January 24, 2025:
    nit in https://github.com/bitcoin/bitcoin/commit/f8b1b218b4f8533128b337168b6769e2e4c30c02: Any reason to re-order this? Should be fine to keep the scopes as-is, since they are so small.

    l0rinc commented at 4:09 pm on January 24, 2025:
    You mean by leaving a hashChecksum reference outside the try, initialize it inside and validate it outside as well? I can do that (or bring them inside in a separate commit), but I didn’t like that. Can you show me with a diff with the version that you like?

    maflcko commented at 4:17 pm on January 24, 2025:
    All good, I see it wouldn’t make the diff smaller. Feel free to resolve.
  22. in src/node/blockstorage.cpp:966 in f72c2dd3a0 outdated
    962@@ -963,23 +963,34 @@ bool BlockManager::WriteBlockUndo(const CBlockUndo& blockundo, BlockValidationSt
    963             return false;
    964         }
    965         // Open history file to append
    966-        AutoFile fileout{OpenUndoFile(pos)};
    967+        AutoFile fileout{m_undo_file_seq.Open(pos, false), {}}; // We'll obfuscate ourselves
    


    maflcko commented at 3:54 pm on January 24, 2025:
    in f72c2dd3a0c5005bb527587dc5576a19dc6a790d: I wonder if it would be more encapsulated to add a new AutoFile::write_large(std::vector<std::byte>&&) method which consumes a large byte blob. This would allow to keep the xor internal to AutoFile, reducing the complexity here and allowing other places to use it as well?

    l0rinc commented at 4:10 pm on January 24, 2025:
    Interesting idea - what do others think?

    l0rinc commented at 7:16 pm on January 26, 2025:
    Done in a separate commit, the result is a lot cleaner, thanks for the suggestion
  23. in src/node/blockstorage.cpp:682 in 2a5c52ac4e outdated
    678@@ -679,7 +679,7 @@ bool BlockManager::ReadBlockUndo(CBlockUndo& blockundo, const CBlockIndex& index
    679     // Open history file to read
    680     AutoFile filein{OpenUndoFile(pos, true)};
    681     if (filein.IsNull()) {
    682-        LogError("OpenUndoFile failed for %s", pos.ToString());
    683+        LogError("%s: OpenUndoFile failed for %s", __func__, pos.ToString());
    


    maflcko commented at 3:57 pm on January 24, 2025:
    nit in 2a5c52ac4e0c098dc6dcf354d9e00fc5c78b6dfe: An alternative would be to say LogError("OpenUndoFile failed for %s while reading", _);

    l0rinc commented at 4:26 pm on January 24, 2025:
    Done
  24. maflcko commented at 4:04 pm on January 24, 2025: member

    2 full IBD runs against master for 870k blocks (seeded from real nodes) indicates a 6% total speedup. Note that this is only measurable with full IBD, not with reindex(-chainstate) since the gain comes from block reading/writing.

    I don’t understand this. -reindex(-chainstate) requires the read of blocks, so why would it not be measurable? See also #28226 which this pull is inspired by(?) and which claims a speedup in reindex-chainstate.

  25. l0rinc force-pushed on Jan 24, 2025
  26. l0rinc commented at 4:30 pm on January 24, 2025: contributor

    which claims a speedup in reindex-chainstate

    So the 9% improvement in unserializing seems to translate to roughly 1.2% total runtime improvement in -reindex-chainstate on my machine.

    I can measure several runs to see if it makes any difference (to be able to claim anything reliable about a ~1% potential speedup), but the reads are only 27% faster, while the writes are 2.9x faster, so I’m not surprised that reindex doesn’t shine compared to IBD. But I’m currently rerunning them with the rebased PR to make sure my measurements were realistic. If you have any concrete measurement you’d like me to do, feel free to specify them.

  27. l0rinc force-pushed on Jan 26, 2025
  28. l0rinc force-pushed on Jan 26, 2025
  29. l0rinc renamed this:
    optimization: bulk reads(27%)/writes(290%) in [undo]block [de]serialization, 6% faster IBD
    optimization: bulk reads(32%)/writes(298%) in [undo]block [de]serialization, ~6% faster IBD
    on Jan 27, 2025
  30. l0rinc commented at 4:48 pm on January 27, 2025: contributor

    which this pull is inspired by(?)

    I did bump into it, but basically reinvented it (not the first time) while investigating why XOR is slow. I’ll add @martinus as a coauthor as well, thanks for the hint @maflcko, he deserves it.


    -reindex(-chainstate) requires the read of blocks, so why would it not be measurable?

    Thanks for the push, I have redone all the measurements: reindex-chainstate is very stable (see the updated PR description for details), two runs indicate a 4% speedup (with GCC, will try with Clang as well since it indicated a bigger speedup in the microbenchmarks):

    0Summary
    1  COMMIT=97b4a50c714c801e08bc02648a9c259f284069c2 ./build/src/bitcoind -datadir=/mnt/my_storage/BitcoinData -stopatheight=880000 -dbcache=30000 -printtoconsole=0 -reindex-chainstate -connect=0 ran
    2    1.04 ± 0.00 times faster than COMMIT=5acf12bafeb126f2190b3f401f95199e0eea90c9 ./build/src/bitcoind -datadir=/mnt/my_storage/BitcoinData -stopatheight=880000 -dbcache=30000 -printtoconsole=0 -reindex-chainstate -connect=0
    

    While IBD is closer to the user’s experience (having actual block- and undo writes, which is important since they were modified here), it’s also less stable, so I ran 3 rounds of each, indicating a 6% speedup (bringing reindex and IBD speeds closer together):

    0Summary
    1  COMMIT=0e9fb2ed330960c0e4cd36b077c64ac7d0f84240 ./build/src/bitcoind -datadir=/mnt/my_storage/BitcoinData -stopatheight=880000 -dbcache=30000 -printtoconsole=0 ran
    2    1.06 ± 0.02 times faster than COMMIT=5acf12bafeb126f2190b3f401f95199e0eea90c9 ./build/src/bitcoind -datadir=/mnt/my_storage/BitcoinData -stopatheight=880000 -dbcache=30000 -printtoconsole=0
    
  31. optimization: Bulk serialization reads in `UndoRead` and `ReadBlock`
    The Obfuscation (XOR) operations are currently done byte-by-byte during serialization, buffering the reads will enable batching the obfuscation operations later (not yet done here).
    
    Also, different operating systems seem to handle file caching differently, so reading bigger batches (and processing those from memory) is also a bit faster (likely because of fewer native fread calls or less locking).
    
    Since `ReadBlock[Undo]` is called with the file position being set after the [undo]block size, we have to start by backtracking 4 bytes to be able to read the expected size first.
    As a consequence, the `FlatFilePos pos` parameter in `ReadBlock` is copied now.
    
    `HashVerifier` was included in the try/catch to include the `undo_size` serialization there as well since the try is about `Deserialize` errors. This is why the final checksum verification was also included in the try.
    
    > cmake -B build -DBUILD_BENCH=ON -DCMAKE_BUILD_TYPE=Release && cmake --build build -j$(nproc) && build/src/bench/bench_bitcoin -filter='ReadBlockBench' -min-time=10000
    
    > C++ compiler .......................... AppleClang 16.0.0.16000026
    
    Before:
    |               ns/op |                op/s |    err% |     total | benchmark
    |--------------------:|--------------------:|--------:|----------:|:----------
    |        2,289,743.62 |              436.73 |    0.3% |     11.03 | `ReadBlockBench`
    
    After:
    |               ns/op |                op/s |    err% |     total | benchmark
    |--------------------:|--------------------:|--------:|----------:|:----------
    |        1,724,703.14 |              579.81 |    0.4% |     11.06 | `ReadBlockBench`
    
    > C++ compiler .......................... GNU 13.3.0
    
    Before:
    |               ns/op |                op/s |    err% |          ins/op |          cyc/op |    IPC |         bra/op |   miss% |     total | benchmark
    |--------------------:|--------------------:|--------:|----------------:|----------------:|-------:|---------------:|--------:|----------:|:----------
    |        7,786,309.20 |              128.43 |    0.0% |   70,832,812.80 |   23,803,523.16 |  2.976 |   5,073,002.56 |    0.4% |     10.72 | `ReadBlockBench`
    
    After:
    |               ns/op |                op/s |    err% |          ins/op |          cyc/op |    IPC |         bra/op |   miss% |     total | benchmark
    |--------------------:|--------------------:|--------:|----------------:|----------------:|-------:|---------------:|--------:|----------:|:----------
    |        6,272,557.28 |              159.42 |    0.0% |   63,251,231.42 |   19,739,780.92 |  3.204 |   3,589,886.66 |    0.3% |     10.57 | `ReadBlockBench`
    
    Co-authored-by: Cory Fields <cory-nospam-@coryfields.com>
    Co-authored-by: Martin Leitner-Ankerl <martin.ankerl@gmail.com>
    0babb8ff48
  32. Add `AutoFile::write_large` for batching obfuscation operations
    Instead of copying the data and doing the xor in a 4096 byte array, we're doing it directly on the input.
    
    `DataStream` constructor was also added to enable presized serialization and writing in a single command.
    6c2d51a306
  33. optimization: Bulk serialization writes in `SaveBlockUndo` and `SaveBlock`
    Similarly to the serialization reads, buffered writes will enable batched xor calculations - especially since currently we need to copy the write inputs Span to do the obfuscation on it, batching enables doing the xor on the internal buffer instead.
    
    > cmake -B build -DBUILD_BENCH=ON -DCMAKE_BUILD_TYPE=Release && cmake --build build -j$(nproc) && build/src/bench/bench_bitcoin -filter='SaveBlockBench' -min-time=10000
    
    > C++ compiler .......................... AppleClang 16.0.0.16000026
    
    Before:
    |               ns/op |                op/s |    err% |     total | benchmark
    |--------------------:|--------------------:|--------:|----------:|:----------
    |        5,267,613.94 |              189.84 |    1.0% |     11.05 | `SaveBlockBench`
    
    After:
    |               ns/op |                op/s |    err% |     total | benchmark
    |--------------------:|--------------------:|--------:|----------:|:----------
    |        1,767,367.40 |              565.81 |    1.6% |     10.86 | `SaveBlockBench`
    
    > C++ compiler .......................... GNU 13.3.0
    
    Before:
    |               ns/op |                op/s |    err% |          ins/op |          cyc/op |    IPC |         bra/op |   miss% |     total | benchmark
    |--------------------:|--------------------:|--------:|----------------:|----------------:|-------:|---------------:|--------:|----------:|:----------
    |        4,128,530.90 |              242.22 |    3.8% |   19,358,001.33 |    8,601,983.31 |  2.250 |   3,079,334.76 |    0.4% |     10.64 | `SaveBlockBench`
    
    After:
    |               ns/op |                op/s |    err% |          ins/op |          cyc/op |    IPC |         bra/op |   miss% |     total | benchmark
    |--------------------:|--------------------:|--------:|----------------:|----------------:|-------:|---------------:|--------:|----------:|:----------
    |        3,130,556.05 |              319.43 |    4.7% |   17,305,378.56 |    6,457,946.37 |  2.680 |   2,579,854.87 |    0.3% |     10.83 | `SaveBlockBench`
    
    Co-authored-by: Cory Fields <cory-nospam-@coryfields.com>
    c16332db60
  34. log: unify error messages for (read/write)[undo]block
    Co-authored-by: maflcko <6399679+maflcko@users.noreply.github.com>
    d700b14491
  35. l0rinc force-pushed on Jan 27, 2025

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2025-02-05 03:13 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me