Skip to content

Conversation

LarryRuane
Copy link
Contributor

@LarryRuane LarryRuane commented Sep 25, 2023

The MallocUsage() function takes an allocation size as an argument and returns the amount of physical memory consumed, which is greater due to memory allocator overhead and alignment. It was first added in 2015 (first commit of #6102), but its accuracy has degraded as memory allocation libraries have evolved. It's used when it's important that large data structures, such as the coins cache and mempool, should use a predictable, configurable (limited) amount of physical memory (see the -dbcache and -maxmempool configuration options), as well as a few other places.

sipa figured out a concise, efficient expression that this function can use, and that's what's implemented here.

Also add a unit test, which is more helpful than usual in this case since platforms, operating systems, and libraries vary significantly in this area.

@DrahtBot
Copy link
Contributor

DrahtBot commented Sep 25, 2023

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/28531.

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:

  • #33021 (test: revive test verifying that GetCoinsCacheSizeState switches from OK→LARGE→CRITICAL by l0rinc)
  • #32588 (util: Abort on failing CHECK_NONFATAL in debug builds by maflcko)
  • #32279 ([IBD] prevector: store P2WSH/P2TR/P2PK scripts inline 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.

LLM Linter (✨ experimental)

Possible typos and grammar issues:

  • larger that size -> larger than that size [“larger that size” should use “than” for comparison]
  • beyojnd -> beyond [typo in “beyo​j​nd”]

drahtbot_id_4_m

@LarryRuane
Copy link
Contributor Author

The results of the old and new versions of this function should differ only slightly; it would be bad if the new one gave very different results, because node operators might find too much memory being consumed, or (not as bad) not enough. To manually test this, I ran -reindex-chainstate on Ubuntu, and watched memory usage by printing /proc/pid/statm and watching the data (6th) field. On master, the value settled to 315140 (units are 4k pages); with this PR it was 315606, which indicates that the new version produces slightly smaller results, but they're close.

@LarryRuane
Copy link
Contributor Author

Changing to draft because CI on a couple of the platforms failed the new test, so the physical memory calculation will need to be different on those platforms, I try to figure that out.

@martinus
Copy link
Contributor

martinus commented Nov 20, 2023

I can reproduce the same results with glibc 2.31 and 2.38, in 32bit and 64bit. I don't think it needs to be perfect on all platforms, I think your new calculation is fine.

I played a bit with a reproducer, here is mine: https://godbolt.org/z/s971sbnhG I refactored your MallocUsage formula a bit, but it's basically the same

@DrahtBot
Copy link
Contributor

🤔 There hasn't been much activity lately and the CI seems to be failing.

If no one reviewed the current pull request by commit hash, a rebase can be considered. While the CI failure may be a false positive, the CI hasn't been running for some time, so there may be a real issue hiding as well. A rebase triggers the latest CI and makes sure that no silent merge conflicts have snuck in.

@LarryRuane LarryRuane marked this pull request as ready for review February 29, 2024 20:07
@LarryRuane
Copy link
Contributor Author

Force-pushed to 04f3fbe - rebase only. (CI is still expected to fail, I'm working on that now.)

@LarryRuane LarryRuane force-pushed the 2023-09-MallocUsage branch 2 times, most recently from cee653f to 86b71ec Compare March 1, 2024 23:22
@LarryRuane LarryRuane force-pushed the 2023-09-MallocUsage branch 3 times, most recently from 6bfdad9 to 58ebf90 Compare March 15, 2024 21:32
@LarryRuane
Copy link
Contributor Author

@martinus
Can you think of why the macOS and Win64 are failing (I have only Ubuntu, which passes)? As an experiment, I changed the memory usage ratio needed to pass to the resource map being just less than std_map, but not even that passes (that is, the resource map uses more space). Both of those platforms fail the same way (you can see this in the CI results, this is Win64):

D:/a/bitcoin/bitcoin/src/test/pool_tests.cpp(183): error: in "pool_tests/memusage_test": 
  check memusage::DynamicUsage(resource_map) <= memusage::DynamicUsage(std_map) * 100 / 100 
  has failed [466624 > 451088]

On earlier runs, some other tests have failed, but I'm not sure if those are spurious failures.

I'm not sure what to do now, any thoughts or suggestions are welcome!

@sipa
Copy link
Member

sipa commented Mar 16, 2024

@LarryRuane There is no reason to assume that the memory allocation overhead on those platforms, with substantially different C libraries, would match the formula we inferred on x86_64 and arm Linux.

If our goal is actually accurate memory usage calculations on all systems, we will need to derive a formula for each supported system separately.

@LarryRuane LarryRuane force-pushed the 2023-09-MallocUsage branch from 58ebf90 to e0fa518 Compare March 19, 2024 02:29
@LarryRuane
Copy link
Contributor Author

LarryRuane commented Mar 19, 2024

@sipa - I don't think the test failures could be due to differences in memory allocation overhead across platforms. The actual memory allocation overhead isn't being tested at all. To do that would probably require a test that uses /proc/meminfo (which doesn't exist on all platforms) or similar.

I don't mind giving up and closing this PR, but as @martinus said in an earlier comment, this calculation doesn't need to be perfect, just better.

I think this test failure must be due to differences in std::unordered_map implementations. That container does various allocations for different reasons, and it must be that with this PR's change in memory usage calculation, the std::unordered_map on macOS and Win64 (at least) are doing more a kind of allocation that the new calculation thinks has higher overhead. Something like that.

[UPDATE: the following discussion about std::unordered_map::reserve() is incorrect, calling reserve() doesn't prevent the bucket array from being reallocated multiple times within the pool resource -- rather, it's reallocated using regular memory. Only allocations up to 128 bytes come from the pool allocator. (I'll probably remove these comments later.)

I thought I had it figured out; I verified with the debugger that as the test adds the 10k entries to the two maps, it has to repeatedly grow the bucket array. The allocation sizes (in bytes) for the bucket array that I saw here on Ubuntu were: 104, 232, 472, 1026, 2056, 4328, 8872, 18856, 40696, 82184.... The tradeoff one makes when using the pool resource allocator is that memory allocations that are freed but then those same sizes not allocated again, those allocations are, in effect, leaked (until the resource is destroyed). The pool resource works great when freeing and allocating the same sizes (rounded up to the alignment, usually 8 bytes) repeatedly. This is, of course, the case for the individual map entries.

So the latest force-push simply calls reserve() initially on both maps (this is only really needed for the pool resource map). Debugging verifies that this does prevent the bucket array from being reallocated, here on Ubuntu. But it didn't fix the problem on at least macOS and Win64. Maybe those platforms' implementations of std::unordered_map ignore the reserve() hint?

It's difficult when CI fails on platforms that I don't have access to. Do others have a solution to that? Can I install macOS on Ubuntu or Windows 10 (I have both) as a VM? Maybe I can set up my Windows laptop to build and run the debugger, but that seems like a lot of work.

@martinus
Copy link
Contributor

martinus commented Mar 20, 2024

@LarryRuane The problem here is that the DynamicUsage(const std::unordered_map<X, Y, Z>& m) just estimates the memory usage by thinking that internally it uses a node with a single pointer (see struct unordered_node : private X in memusage.h). This estimation is probably not correct on all platforms, e.g. windows seems to use a double linked list, so this underestimates actual memory usage.

The inconcsistency now comes when using DynamicUsage with a pool resource. Here the actual real world memory usage is counted (because it uses a custom allocator, there's no need for estimating node size), and here the different implementations actually effect the result.

So, with your new MallocUsage the numbers are most likely more correct, but this seems to trigger the incorrect underestimation for DynamicUsage(const std::unordered_map<X, Y, Z>& m)

@LarryRuane
Copy link
Contributor Author

@martinus - thanks, that makes perfect sense! I hadn't thought of the possibility of the nodes having two pointers instead of one (double instead of single linked list). Seems like a bad design, but anyway.

I don't think there would be much benefit to fixing DynamicUsage(const std::unordered_map<X, Y, Z>& m) to account for this (make it dependent on platform), because this function is no longer important since we're using the pool resource. It's probably really used only in the test. So it's really just a test problem. I'll see what I can do to fix this.

@@ -101,6 +110,7 @@ def send_batch(fee):
test_framework.log.debug("Check that mempoolminfee is larger than minrelaytxfee")
assert_equal(node.getmempoolinfo()['minrelaytxfee'], Decimal('0.00001000'))
assert_greater_than(node.getmempoolinfo()['mempoolminfee'], Decimal('0.00001000'))
test_framework.sync_mempools()
Copy link
Member

Choose a reason for hiding this comment

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

https://cirrus-ci.com/task/4825274484785152?logs=ci#L3624

in sync_mempools
[23:01:19.556]                                        raise AssertionError("Mempool sync timed out after {}s:{}".format(
[23:01:19.556]                                    AssertionError: Mempool sync timed out after 2400s:
[23:01:19.556] 


// Fill to just beyojnd the cache size limit.
Copy link
Member

Choose a reason for hiding this comment

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

that size -> than size [incorrect preposition]
beyojnd -> beyond [typographical error]

Copy link
Contributor

@l0rinc l0rinc left a comment

Choose a reason for hiding this comment

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

Thanks for getting back to this change.
We should synchronize it with CCoinsMap, chich already claims to account for an "overhead of 1 or 2 pointers".
Also, the test should pass before the change as well, so it would be helpful to add it as a separate commit before the change to make it easy to see how it behaves before and after the change as well.
The test still contains a lot of repetition, please see my suggestion on how to compact it a bit more.
There are still uncovered parts of the code, I'd feel more comfortable if all modified code parts are exercised by tests.

Copy link
Contributor

Choose a reason for hiding this comment

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

@LarryRuane I think you should probably be the author of the commit, given that you've already added @theStack as a co-author

src/memusage.h Outdated
}

template<typename X, typename Y, typename Z>
static inline size_t DynamicUsage(const std::unordered_map<X, Y, Z>& m)
{
return MallocUsage(sizeof(unordered_node<std::pair<const X, Y> >)) * m.size() + MallocUsage(sizeof(void*) * m.bucket_count());
return MallocUsage(sizeof(unordered_node<std::pair<const X, Y> >)) * m.size() + MallocUsage(2 * sizeof(void*) * m.bucket_count());
Copy link
Contributor

Choose a reason for hiding this comment

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

I really dislike comments when code could be used, i.e. when I see sizeof(void*), it doesn't tell me anything about what we're actually measuring ... 2 * sizeof(void*) is even worse.

I was thinking of showing exactly what we're measuring here, something like:

// Empirically, an std::unordered_map node has two pointers (likely
// forward and backward pointers) on some platforms (Windows and macOS),
// so be conservative in estimating memory usage by assuming this is
// the case for all platforms.
template <typename X>
struct unordered_node : private X
{
    void* next_ptr;
    void* prev_ptr;
};

// The memory used by an unordered_set or unordered_map is the sum of the
// sizes of the individual nodes (which are separately allocated) plus
// the size of the bucket array (which is a single allocation).
// Empirically, each element of the bucket array consists of two pointers
// on some platforms (Windows and macOS), so be conservative.
template <typename X, typename Y>
static size_t DynamicUsage(const std::unordered_set<X, Y>& s)
{
    return MallocUsage(sizeof(unordered_node<X>)) * s.size() +
           MallocUsage((sizeof(unordered_node<X>::next_ptr) + sizeof(unordered_node<X>::prev_ptr)) * s.bucket_count());
}

template <typename X, typename Y, typename Z>
static size_t DynamicUsage(const std::unordered_map<X, Y, Z>& m)
{
    return MallocUsage(sizeof(unordered_node<std::pair<const X, Y>>)) * m.size() +
           MallocUsage((sizeof(unordered_node<std::pair<const X, Y>>::next_ptr) + sizeof(unordered_node<std::pair<const X, Y>>::prev_ptr)) * m.bucket_count());
}

Also note that the current test doesn't doesn't exercise these modified lines at all, so we've kinda' in the dark here...

src/memusage.h Outdated
};

// The memory used by an unordered_set or unordered map is the sum of the
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
// The memory used by an unordered_set or unordered map is the sum of the
// The memory used by an unordered_set or unordered_map is the sum of the

@@ -212,7 +221,9 @@ static inline size_t DynamicUsage(const std::unordered_map<Key,
size_t estimated_list_node_size = MallocUsage(sizeof(void*) * 3);
size_t usage_resource = estimated_list_node_size * pool_resource->NumAllocatedChunks();
size_t usage_chunks = MallocUsage(pool_resource->ChunkSizeBytes()) * pool_resource->NumAllocatedChunks();
return usage_resource + usage_chunks + MallocUsage(sizeof(void*) * m.bucket_count());
// Empirically, each element of the bucket array has two pointers on some platforms (Windows and macOS).
Copy link
Contributor

Choose a reason for hiding this comment

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

Instead of empirically, can we add documentation or source code links here?

chainstate.GetCoinsCacheSizeState(MAX_COINS_CACHE_BYTES, /*max_mempool_size_bytes=*/0),
CoinsCacheSizeState::OK);
}
BOOST_CHECK_LT(i, 80'000);
Copy link
Contributor

Choose a reason for hiding this comment

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

I really dislike that we're exposing the loop variable just to see if we finished without transitioning.
We seem to exit at worst around 32415 for me locally, maybe we can reduce the attempt count and extract it to a variable:

constexpr size_t MAX_ATTEMPTS{50'000};               //  runaway-loop safety cap

And we can add a worst-case condition for the very last iteration which should always be LARGE, e.g.:

// OK → LARGE
for (size_t i{1}; i <= MAX_ATTEMPTS; ++i) {
    AddTestCoin(m_rng, view);

    auto state{chainstate.GetCoinsCacheSizeState(MAX_COINS_CACHE_BYTES, max_mempool_size_bytes)};
    if (i == MAX_ATTEMPTS || view.DynamicMemoryUsage() >= full_cap * 90 / 100) {
        BOOST_CHECK_EQUAL(state, CoinsCacheSizeState::LARGE);
        break;
    }
    BOOST_CHECK_EQUAL(state, CoinsCacheSizeState::OK);
}

constexpr unsigned int COIN_SIZE = is_64_bit ? 80 : 64;
// An empty coins cache still allocates one PoolResource 'chunk', which is 256 KiB, and there
// is some overhead. As a sanity check, an empty coins cache should be only slightly larger.
BOOST_CHECK_LT(view.DynamicMemoryUsage(), 256 * 1024 * 100 / 98);
Copy link
Contributor

Choose a reason for hiding this comment

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

I find the 100/98 a weird way to express a percentage - if we simply want to check that it's roughly 256 KiB, we could check their ratio:

Suggested change
BOOST_CHECK_LT(view.DynamicMemoryUsage(), 256 * 1024 * 100 / 98);
BOOST_CHECK_LT(view.DynamicMemoryUsage() / (256 * 1024.0), 1.1);

BOOST_CHECK_EQUAL(
chainstate.GetCoinsCacheSizeState(MAX_COINS_CACHE_BYTES, /*max_mempool_size_bytes=*/ 1 << 19),
chainstate.GetCoinsCacheSizeState(MAX_COINS_CACHE_BYTES, /*max_mempool_size_bytes=*/MAX_MEMPOOL_CACHE_BYTES),
Copy link
Contributor

Choose a reason for hiding this comment

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

it makes sense to add the /*max_mempool_size_bytes=* for primitives - but we don't usually do it for self-explanatory variables:

Suggested change
chainstate.GetCoinsCacheSizeState(MAX_COINS_CACHE_BYTES, /*max_mempool_size_bytes=*/MAX_MEMPOOL_CACHE_BYTES),
chainstate.GetCoinsCacheSizeState(MAX_COINS_CACHE_BYTES, MAX_MEMPOOL_CACHE_BYTES),

BOOST_CHECK_EQUAL(
chainstate.GetCoinsCacheSizeState(MAX_COINS_CACHE_BYTES, /*max_mempool_size_bytes=*/0),
CoinsCacheSizeState::CRITICAL);

// Passing non-zero max mempool usage (512 KiB) should allow us more headroom.
// Repeat (continuing with the existing cache) but with a non-zero max mempool;
Copy link
Contributor

Choose a reason for hiding this comment

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

hmmm, we're repeating the same steps but with different data?
Can we separate the data from the algorithm and do the iteration in something like:

for (size_t max_mempool_size_bytes : {size_t{0}, MAX_MEMPOOL_CACHE_BYTES}) {
  // The steps from OK to CRITICAL
}
For simplicity, here's the full `getcoinscachesizestate` test
// Copyright (c) 2019-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <sync.h>
#include <test/util/coins.h>
#include <test/util/random.h>
#include <test/util/setup_common.h>
#include <validation.h>

#include <boost/test/unit_test.hpp>

BOOST_FIXTURE_TEST_SUITE(validation_flush_tests, TestingSetup)

//! Verify that Chainstate::GetCoinsCacheSizeState() switches from OK→LARGE→CRITICAL
//! at the expected utilization thresholds, first with *no* mempool head-room,
//! then with additional mempool head-room.
BOOST_AUTO_TEST_CASE(getcoinscachesizestate)
{
    Chainstate& chainstate{m_node.chainman->ActiveChainstate()};

    LOCK(::cs_main);
    CCoinsViewCache& view = chainstate.CoinsTip();
    BOOST_CHECK_LT(view.DynamicMemoryUsage() / (256 * 1024.0), 1.1);

    constexpr size_t MAX_COINS_CACHE_BYTES{8'000'000};   //  ~8 MB cache size for the test
    constexpr size_t MAX_MEMPOOL_CACHE_BYTES{4'000'000}; //  ~4 MB extra head-room
    constexpr size_t MAX_ATTEMPTS{50'000};               //  runaway-loop safety cap

    // Run the same growth-path twice: first with 0 head-room, then with extra head-room
    for (size_t max_mempool_size_bytes : {size_t{0}, MAX_MEMPOOL_CACHE_BYTES}) {
        BOOST_CHECK_EQUAL(chainstate.GetCoinsCacheSizeState(MAX_COINS_CACHE_BYTES, max_mempool_size_bytes), CoinsCacheSizeState::OK);

        const size_t full_cap = MAX_COINS_CACHE_BYTES + max_mempool_size_bytes;

        // OK → LARGE
        for (size_t i{1}; i <= MAX_ATTEMPTS; ++i) {
            AddTestCoin(m_rng, view);

            auto state{chainstate.GetCoinsCacheSizeState(MAX_COINS_CACHE_BYTES, max_mempool_size_bytes)};
            if (i == MAX_ATTEMPTS || view.DynamicMemoryUsage() >= full_cap * 90 / 100) {
                BOOST_CHECK_EQUAL(state, CoinsCacheSizeState::LARGE);
                break;
            }
            BOOST_CHECK_EQUAL(state, CoinsCacheSizeState::OK);
        }

        // LARGE → CRITICAL
        for (size_t i{1}; i <= MAX_ATTEMPTS; ++i) {
            AddTestCoin(m_rng, view);

            auto state{chainstate.GetCoinsCacheSizeState(MAX_COINS_CACHE_BYTES, max_mempool_size_bytes)};
            if (i == MAX_ATTEMPTS || view.DynamicMemoryUsage() > full_cap) {
                BOOST_CHECK_EQUAL(state, CoinsCacheSizeState::CRITICAL);
                break;
            }
            BOOST_CHECK_EQUAL(state, CoinsCacheSizeState::LARGE);
        }
    }

    for (int i{0}; i < 1'000; ++i) {
        AddTestCoin(m_rng, view);
        BOOST_CHECK_EQUAL(chainstate.GetCoinsCacheSizeState(), CoinsCacheSizeState::OK);
    }

    // CRITICAL → OK via Flush
    BOOST_CHECK_EQUAL(chainstate.GetCoinsCacheSizeState(MAX_COINS_CACHE_BYTES, /*mempool=*/0), CoinsCacheSizeState::CRITICAL);
    view.SetBestBlock(m_rng.rand256());
    BOOST_CHECK(view.Flush());
    BOOST_CHECK_EQUAL(chainstate.GetCoinsCacheSizeState(MAX_COINS_CACHE_BYTES, /*mempool=*/0), CoinsCacheSizeState::OK);
}

BOOST_AUTO_TEST_SUITE_END()

Copy link
Contributor

Choose a reason for hiding this comment

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

I have extracted the suggested test to a separate PR: #33021

@@ -212,7 +221,9 @@ static inline size_t DynamicUsage(const std::unordered_map<Key,
size_t estimated_list_node_size = MallocUsage(sizeof(void*) * 3);
size_t usage_resource = estimated_list_node_size * pool_resource->NumAllocatedChunks();
size_t usage_chunks = MallocUsage(pool_resource->ChunkSizeBytes()) * pool_resource->NumAllocatedChunks();
return usage_resource + usage_chunks + MallocUsage(sizeof(void*) * m.bucket_count());
// Empirically, each element of the bucket array has two pointers on some platforms (Windows and macOS).
size_t usage_bucket_array = MallocUsage(2 * sizeof(void*) * m.bucket_count());
Copy link
Contributor

Choose a reason for hiding this comment

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

https://github.com/bitcoin/bitcoin/blob/master/src/coins.h#L219 already claims to account for 1-2 pointers, do we need any other change to synchronize it with the current PR?

@l0rinc
Copy link
Contributor

l0rinc commented Jun 4, 2025

I understand the difficulties of guessing the correct memory usage of such an app (especially when the user cannot even provide total memory usage requirements, just dbcache ones), trying to find a formula that is good enough on all OSs, compilers, versions, 32/64 bits, architectures, etc.
I ran a simple benchmark to see if this memory accounting changed the behavior of IBD (simulated via a reindex-chainstate with default dbcache=450 until block 888,888).

For reference, the commits I used are:

  • 3f83c74 - master with old MallocUsage
  • 4228018 - this PR with new MallocUsage
The PR introduces a ~2% slowdown
COMMITS="3f83c744ac28b700090e15b5dda2260724a56f49 4228018ace848adcafd197776cbb4afc2400bf16"; \
STOP=888888; DBCACHE=450; \
CC=gcc; CXX=g++; \
BASE_DIR="/mnt/my_storage"; DATA_DIR="$BASE_DIR/BitcoinData"; LOG_DIR="$BASE_DIR/logs"; \
(echo ""; for c in $COMMITS; do git fetch -q origin $c && git log -1 --pretty='%h %s' $c || exit 1; done; echo "") && \
hyperfine \
  --sort command \
  --runs 1 \
  --export-json "$BASE_DIR/rdx-$(sed -E 's/(\w{8})\w+ ?/\1-/g;s/-$//'<<<"$COMMITS")-$STOP-$DBCACHE-$CC.json" \
  --parameter-list COMMIT ${COMMITS// /,} \
  --prepare "killall bitcoind; rm -f $DATA_DIR/debug.log; git checkout {COMMIT}; git clean -fxd; git reset --hard && \
    cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=Release && ninja -C build bitcoind && \
    ./build/bin/bitcoind -datadir=$DATA_DIR -stopatheight=$STOP -dbcache=10000 -printtoconsole=0; sleep 10" \
  --cleanup "cp $DATA_DIR/debug.log $LOG_DIR/debug-{COMMIT}-$(date +%s).log" \
  "COMPILER=$CC ./build/bin/bitcoind -datadir=$DATA_DIR -stopatheight=$STOP -dbcache=$DBCACHE -reindex-chainstate -blocksonly -connect=0 -printtoconsole=0"

3f83c74 Merge #32526: fuzz: Delete wallet_notifications
4228018 improve MallocUsage() accuracy

Benchmark 1: COMPILER=gcc ./build/bin/bitcoind -datadir=/mnt/my_storage/BitcoinData -stopatheight=888888 -reindex-chainstate -blocksonly -connect=0 -printtoconsole=0 -dbcache=450 (COMMIT = 3f83c744ac28b700090e15b5dda2260724a56f49)
  Time (abs ≡):        19573.674 s               [User: 35453.443 s, System: 2822.880 s]

Benchmark 2: COMPILER=gcc ./build/bin/bitcoind -datadir=/mnt/my_storage/BitcoinData -stopatheight=888888 -reindex-chainstate -blocksonly -connect=0 -printtoconsole=0 -dbcache=450 (COMMIT = 4228018ace848adcafd197776cbb4afc2400bf16)
  Time (abs ≡):        20031.162 s               [User: 36761.112 s, System: 2992.418 s]
Relative speed comparison
        1.00          COMPILER=gcc ./build/bin/bitcoind -datadir=/mnt/my_storage/BitcoinData -stopatheight=888888 -reindex-chainstate -blocksonly -connect=0 -printtoconsole=0 -dbcache=450 (COMMIT = 3f83c744ac28b700090e15b5dda2260724a56f49)
        1.02          COMPILER=gcc ./build/bin/bitcoind -datadir=/mnt/my_storage/BitcoinData -stopatheight=888888 -reindex-chainstate -blocksonly -connect=0 -printtoconsole=0 -dbcache=450 (COMMIT = 4228018ace848adcafd197776cbb4afc2400bf16)

To understand the performance and memory implications, I ran the same benchmark with Massif profiling, revealing that after this PR we're using ~4% less total memory now

3f83c74 has 790MB peak
    MB
790.2^#
     |#:   :  :           :        :                           :
     |#:   :  :        :  :        :               :  :  :: : :: ::   @   :
     |#::  :  :        :  :        :       :     : :  :  :: : :: ::   @   :
     |#::  :  :        :  :        :       :     :::  : ::: : :: ::   @   : :
     |#::  :  : :      :: : :      :      ::   : :::  : ::: : :: ::  :@   : ::
     |#::  :  ::: :    :: : :     :::::   :::  : :::  ::::::: :: ::  :@:  : ::
     |#::  :  :::::    :: : :  : :::: :   :::: : :::: ::::::: :: ::  :@:  : ::
     |#::  :  :::::   ::: : :  : :::: : :::::: : :::: ::::@::::: :: ::@:: : ::
     |#:: ::  :::::   :::::::  : :::: ::: :::::: :::: ::::@::::: :: ::@:::: ::
     |#:::::  ::::::  ::::::: :: :::: ::: ::::::::::::::::@::::: :: ::@:::: @:
     |#::::: :::::::  :::::::::: :::: ::: ::::::::::@:::::@:::::@:: ::@:::: @:
     |#::::: ::::::::::::::::::: :::: ::: ::::::::::@:::::@:::::@:: ::@:::::@:
     |#:::::::::::::::::::::::::::::: ::: ::::::::::@:::::@:::::@:::::@:::::@:
     |#:::::::::::::::::::::::::::::: ::: ::::::::::@:::::@:::::@:::::@:::::@:
     |#:::::::::::::::::::::::::::::: ::: ::::::::::@:::::@:::::@:::::@:::::@:
     |#:::::::::::::::::::::::::::::: ::: ::::::::::@:::::@:::::@:::::@:::::@:
     |#:::::::::::::::::::::::::::::: ::: ::::::::::@:::::@:::::@:::::@:::::@:
     |#:::::::::::::::::::::::::::::: ::: ::::::::::@:::::@:::::@:::::@:::::@:
     |#:::::::::::::::::::::::::::::: ::: ::::::::::@:::::@:::::@:::::@:::::@:
   0 +----------------------------------------------------------------------->h
     0                                                                   77.36
4228018 has 760MB peak
    MB
760.9^                                                      ##
     |               @@        @                            #        :   :
     |               @         @    :::           ::        #        :   ::
     |  ::     :     @  :      @    : : ::        :         #  :::   :   ::
     |  : ::   :  :: @  :  ::  @    : : : : :    :: ::      #  ::    :   ::
     |  : : :: :  :  @  :  :   @    : : : : :  :::: :       #  :: @  :   ::
     |  : : : ::  :  @  :  :   @ :: : :@: : :  : :: :       #  :: @  :   ::
     |  : : : ::  :  @  :  :   @ : :: :@: : :  : :: : ::    #  :: @  :   ::
     | :: : : ::  :  @ ::  :   @ : :: :@: : :  : :: : :     #  :: @ ::  ::::
     | :: : : ::  :  @ ::  :   @:: :: :@: : :::: :: : : ::  #  :: @ ::  ::::
     | :: : : ::  : :@ :::::   @:: :: :@: :@:: : :: : : : ::#  :: @ ::  :::: :
     | :: : : ::::: :@ ::: : ::@:: :: :@: :@:: : :: : : : : #  :: @ ::::::::@:
     | :: : : ::: : :@ ::: : : @:: :: :@: :@:: : :: : : : : #  :: @:::: ::::@:
     | :: : : ::: : :@ ::: : : @:: :: :@: :@:: : :: : : : : # ::: @:::: ::::@:
     | :: : : ::: : :@ ::: : : @:: :: :@: :@:: : :: : : : : # ::: @:::: ::::@:
     | :: : : ::: : :@ ::: : : @:: :: :@: :@:: : :: : : : : # ::: @:::: ::::@:
     | :: : : ::: : :@ ::: : : @:: :: :@: :@:: : :: : : : : # ::: @:::: ::::@:
     | :: : : ::: : :@ ::: : : @:: :: :@: :@:: : :: : : : : # ::: @:::: ::::@:
     | :: : : ::: : :@ ::: : : @:: :: :@: :@:: : :: : : : : # ::: @:::: ::::@:
     | :: : : ::: : :@ ::: : : @:: :: :@: :@:: : :: : : : : # ::: @:::: ::::@:
   0 +----------------------------------------------------------------------->h
     0                                                                   79.52

It's not immediately obvious if this is more accurate than before, so I've checked the dbcache related memory usages, which we can see in the logs as:

Using 440.0 MiB for in-memory UTXO set (plus up to 4.8 MiB of unused mempool space)

3f83c74 - 414,449,664B for nodes + 47,738,776B for buckets = ~440MiB dbcache usage
->50.02% (414,449,664B) 0x7D42A2: std::__detail::_Hash_node<std::pair<COutPoint const, CCoinsCacheEntry>, false>* std::__detail::_Hashtable_alloc<PoolAllocator<std::__detail::_Hash_node<std::pair<COutPoint const, CCoinsCacheEntry>, false>, 144ul, 8ul> >::_M_allocate_node<std::piecewise_construct_t const&, std::tuple<COutPoint const&>, std::tuple<> >(std::piecewise_construct_t const&, std::tuple<COutPoint const&>&&, std::tuple<>&&) [clone .isra.0] (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| ->48.66% (403,177,472B) 0x7D5F9B: CCoinsViewCache::BatchWrite(CoinsViewCacheCursor&, uint256 const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | ->48.66% (403,177,472B) 0x7D4C15: CCoinsViewCache::Flush() (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |   ->48.66% (403,177,472B) 0x528158: Chainstate::ConnectTip(BlockValidationState&, CBlockIndex*, std::shared_ptr<CBlock const> const&, ConnectTrace&, DisconnectedBlockTransactions&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |     ->48.66% (403,177,472B) 0x52E7C5: Chainstate::ActivateBestChainStep(BlockValidationState&, CBlockIndex*, std::shared_ptr<CBlock const> const&, bool&, ConnectTrace&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |       ->48.66% (403,177,472B) 0x52EEA3: Chainstate::ActivateBestChain(BlockValidationState&, std::shared_ptr<CBlock const>) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |         ->48.66% (403,177,472B) 0x30AD44: node::ImportBlocks(ChainstateManager&, std::span<fs::path const, 18446744073709551615ul>) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |           ->48.66% (403,177,472B) 0x27800F: std::_Function_handler<void (), AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::{lambda()
| |             ->48.66% (403,177,472B) 0x941FCE: util::TraceThread(std::basic_string_view<char, std::char_traits<char> >, std::function<void ()>) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |               ->48.66% (403,177,472B) 0x2669BA: std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)(std::basic_string_view<char, std::char_traits<char> >, std::function<void ()>), char const*, AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::{lambda()
| |                 ->48.66% (403,177,472B) 0x4B11DB3: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.33)
| |                   ->48.66% (403,177,472B) 0x4E56AA3: start_thread (pthread_create.c:447)
| |                     ->48.66% (403,177,472B) 0x4EE3A33: clone (clone.S:100)
| |
| ->01.36% (11,272,192B) 0x7D50F2: CCoinsViewCache::FetchCoin(COutPoint const&) const (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | ->01.36% (11,272,192B) 0x7D51E9: CCoinsViewCache::GetCoin(COutPoint const&) const (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | | ->01.36% (11,272,192B) 0x7D4FFA: CCoinsViewCache::FetchCoin(COutPoint const&) const (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | |   ->01.36% (11,272,192B) 0x7D543C: CCoinsViewCache::HaveCoin(COutPoint const&) const (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | |     ->01.36% (11,272,192B) 0x518713: Chainstate::ConnectBlock(CBlock const&, BlockValidationState&, CBlockIndex*, CCoinsViewCache&, bool) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | |       ->01.36% (11,272,192B) 0x527CC8: Chainstate::ConnectTip(BlockValidationState&, CBlockIndex*, std::shared_ptr<CBlock const> const&, ConnectTrace&, DisconnectedBlockTransactions&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | |         ->01.36% (11,272,192B) 0x52E7C5: Chainstate::ActivateBestChainStep(BlockValidationState&, CBlockIndex*, std::shared_ptr<CBlock const> const&, bool&, ConnectTrace&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | |           ->01.36% (11,272,192B) 0x52EEA3: Chainstate::ActivateBestChain(BlockValidationState&, std::shared_ptr<CBlock const>) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | |             ->01.36% (11,272,192B) 0x30AD44: node::ImportBlocks(ChainstateManager&, std::span<fs::path const, 18446744073709551615ul>) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | |               ->01.36% (11,272,192B) 0x27800F: std::_Function_handler<void (), AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::{lambda()
| | |                 ->01.36% (11,272,192B) 0x941FCE: util::TraceThread(std::basic_string_view<char, std::char_traits<char> >, std::function<void ()>) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | |                   ->01.36% (11,272,192B) 0x2669BA: std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)(std::basic_string_view<char, std::char_traits<char> >, std::function<void ()>), char const*, AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::{lambda()
| | |                     ->01.36% (11,272,192B) 0x4B11DB3: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.33)
| | |                       ->01.36% (11,272,192B) 0x4E56AA3: start_thread (pthread_create.c:447)
| | |                         ->01.36% (11,272,192B) 0x4EE3A33: clone (clone.S:100)
| | |
| | ->00.00% (0B) in 1+ places, all below ms_print's threshold (01.00%)
| |
| ->00.00% (0B) in 1+ places, all below ms_print's threshold (01.00%)
|
->21.67% (179,561,400B) 0x30D5A9: node::BlockManager::InsertBlockIndex(uint256 const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| ->10.84% (89,842,600B) 0x3114E9: kernel::BlockTreeDB::LoadBlockIndexGuts(Consensus::Params const&, std::function<CBlockIndex* (uint256 const&)>, util::SignalInterrupt const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | ->10.84% (89,842,600B) 0x311900: node::BlockManager::LoadBlockIndex(std::optional<uint256> const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |   ->10.84% (89,842,600B) 0x31238C: node::BlockManager::LoadBlockIndexDB(std::optional<uint256> const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |     ->10.84% (89,842,600B) 0x52449F: ChainstateManager::LoadBlockIndex() (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |       ->10.84% (89,842,600B) 0x320D97: node::CompleteChainstateInitialization(ChainstateManager&, node::ChainstateLoadOptions const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |         ->10.84% (89,842,600B) 0x321F52: node::LoadChainstate(ChainstateManager&, kernel::CacheSizes const&, node::ChainstateLoadOptions const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |           ->10.84% (89,842,600B) 0x2726C4: InitAndLoadChainstate(node::NodeContext&, bool, bool, kernel::CacheSizes const&, ArgsManager const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |             ->10.84% (89,842,600B) 0x27BDAF: AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |               ->10.84% (89,842,600B) 0x23CB15: main (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |
| ->10.83% (89,718,800B) 0x311503: kernel::BlockTreeDB::LoadBlockIndexGuts(Consensus::Params const&, std::function<CBlockIndex* (uint256 const&)>, util::SignalInterrupt const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|   ->10.83% (89,718,800B) 0x311900: node::BlockManager::LoadBlockIndex(std::optional<uint256> const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|     ->10.83% (89,718,800B) 0x31238C: node::BlockManager::LoadBlockIndexDB(std::optional<uint256> const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|       ->10.83% (89,718,800B) 0x52449F: ChainstateManager::LoadBlockIndex() (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|         ->10.83% (89,718,800B) 0x320D97: node::CompleteChainstateInitialization(ChainstateManager&, node::ChainstateLoadOptions const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|           ->10.83% (89,718,800B) 0x321F52: node::LoadChainstate(ChainstateManager&, kernel::CacheSizes const&, node::ChainstateLoadOptions const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|             ->10.83% (89,718,800B) 0x2726C4: InitAndLoadChainstate(node::NodeContext&, bool, bool, kernel::CacheSizes const&, ArgsManager const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|               ->10.83% (89,718,800B) 0x27BDAF: AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|                 ->10.83% (89,718,800B) 0x23CB15: main (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|
->06.10% (50,585,543B) 0x7B792D: leveldb::Arena::AllocateNewBlock(unsigned long) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| ->06.10% (50,573,312B) 0x7B7A90: leveldb::Arena::AllocateFallback(unsigned long) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | ->04.82% (39,923,712B) 0x79CE20: leveldb::MemTable::Add(unsigned long, leveldb::ValueType, leveldb::Slice const&, leveldb::Slice const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | | ->04.15% (34,418,688B) 0x7AE513: leveldb::WriteBatch::Iterate(leveldb::WriteBatch::Handler*) const (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | | | ->04.15% (34,418,688B) 0x7AEBA4: leveldb::WriteBatchInternal::InsertInto(leveldb::WriteBatch const*, leveldb::MemTable*) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | | |   ->04.15% (34,418,688B) 0x78AAFF: leveldb::DBImpl::Write(leveldb::WriteOptions const&, leveldb::WriteBatch*) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | | |     ->04.15% (34,418,688B) 0x59710D: CDBWrapper::WriteBatch(CDBBatch&, bool) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | | |       ->04.15% (34,418,688B) 0x4DE3DF: CCoinsViewDB::BatchWrite(CoinsViewCacheCursor&, uint256 const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | | |         ->04.15% (34,418,688B) 0x7D4C15: CCoinsViewCache::Flush() (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | | |           ->04.15% (34,418,688B) 0x525634: Chainstate::FlushStateToDisk(BlockValidationState&, FlushStateMode, int) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | | |             ->04.15% (34,418,688B) 0x5283D7: Chainstate::ConnectTip(BlockValidationState&, CBlockIndex*, std::shared_ptr<CBlock const> const&, ConnectTrace&, DisconnectedBlockTransactions&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | | |               ->04.15% (34,418,688B) 0x52E7C5: Chainstate::ActivateBestChainStep(BlockValidationState&, CBlockIndex*, std::shared_ptr<CBlock const> const&, bool&, ConnectTrace&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | | |                 ->04.15% (34,418,688B) 0x52EEA3: Chainstate::ActivateBestChain(BlockValidationState&, std::shared_ptr<CBlock const>) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | | |                   ->04.15% (34,418,688B) 0x30AD44: node::ImportBlocks(ChainstateManager&, std::span<fs::path const, 18446744073709551615ul>) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | | |                     ->04.15% (34,418,688B) 0x27800F: std::_Function_handler<void (), AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::{lambda()
| | | |                       ->04.15% (34,418,688B) 0x941FCE: util::TraceThread(std::basic_string_view<char, std::char_traits<char> >, std::function<void ()>) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | | |                         ->04.15% (34,418,688B) 0x2669BA: std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)(std::basic_string_view<char, std::char_traits<char> >, std::function<void ()>), char const*, AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::{lambda()
| | | |                           ->04.15% (34,418,688B) 0x4B11DB3: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.33)
| | | |                             ->04.15% (34,418,688B) 0x4E56AA3: start_thread (pthread_create.c:447)
| | | |                               ->04.15% (34,418,688B) 0x4EE3A33: clone (clone.S:100)
| | | |
| | | ->00.66% (5,505,024B) in 1+ places, all below ms_print's threshold (01.00%)
| | |
| | ->01.29% (10,649,600B) 0x7B7B5C: leveldb::Arena::AllocateAligned(unsigned long) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |   ->01.28% (10,637,312B) 0x79D7D9: leveldb::SkipList<char const*, leveldb::MemTable::KeyComparator>::Insert(char const* const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |   | ->01.28% (10,637,312B) 0x79CDEB: leveldb::MemTable::Add(unsigned long, leveldb::ValueType, leveldb::Slice const&, leveldb::Slice const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |   |   ->01.03% (8,548,352B) 0x7AE513: leveldb::WriteBatch::Iterate(leveldb::WriteBatch::Handler*) const (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |   |   | ->01.03% (8,548,352B) 0x7AEBA4: leveldb::WriteBatchInternal::InsertInto(leveldb::WriteBatch const*, leveldb::MemTable*) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |   |   |   ->01.03% (8,548,352B) 0x78AAFF: leveldb::DBImpl::Write(leveldb::WriteOptions const&, leveldb::WriteBatch*) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |   |   |     ->01.03% (8,548,352B) 0x59710D: CDBWrapper::WriteBatch(CDBBatch&, bool) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |   |   |       ->01.03% (8,548,352B) 0x4DE3DF: CCoinsViewDB::BatchWrite(CoinsViewCacheCursor&, uint256 const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |   |   |         ->01.03% (8,548,352B) 0x7D4C15: CCoinsViewCache::Flush() (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |   |   |           ->01.03% (8,548,352B) 0x525634: Chainstate::FlushStateToDisk(BlockValidationState&, FlushStateMode, int) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |   |   |             ->01.03% (8,548,352B) 0x5283D7: Chainstate::ConnectTip(BlockValidationState&, CBlockIndex*, std::shared_ptr<CBlock const> const&, ConnectTrace&, DisconnectedBlockTransactions&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |   |   |               ->01.03% (8,548,352B) 0x52E7C5: Chainstate::ActivateBestChainStep(BlockValidationState&, CBlockIndex*, std::shared_ptr<CBlock const> const&, bool&, ConnectTrace&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |   |   |                 ->01.03% (8,548,352B) 0x52EEA3: Chainstate::ActivateBestChain(BlockValidationState&, std::shared_ptr<CBlock const>) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |   |   |                   ->01.03% (8,548,352B) 0x30AD44: node::ImportBlocks(ChainstateManager&, std::span<fs::path const, 18446744073709551615ul>) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |   |   |                     ->01.03% (8,548,352B) 0x27800F: std::_Function_handler<void (), AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::{lambda()
| |   |   |                       ->01.03% (8,548,352B) 0x941FCE: util::TraceThread(std::basic_string_view<char, std::char_traits<char> >, std::function<void ()>) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |   |   |                         ->01.03% (8,548,352B) 0x2669BA: std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)(std::basic_string_view<char, std::char_traits<char> >, std::function<void ()>), char const*, AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::{lambda()
| |   |   |                           ->01.03% (8,548,352B) 0x4B11DB3: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.33)
| |   |   |                             ->01.03% (8,548,352B) 0x4E56AA3: start_thread (pthread_create.c:447)
| |   |   |                               ->01.03% (8,548,352B) 0x4EE3A33: clone (clone.S:100)
| |   |   |
| |   |   ->00.25% (2,088,960B) in 1+ places, all below ms_print's threshold (01.00%)
| |   |
| |   ->00.00% (12,288B) in 1+ places, all below ms_print's threshold (01.00%)
| |
| ->00.00% (12,231B) in 1+ places, all below ms_print's threshold (01.00%)
|
->05.76% (47,738,776B) 0x7D730C: std::__detail::_Hashtable_alloc<PoolAllocator<std::__detail::_Hash_node<std::pair<COutPoint const, CCoinsCacheEntry>, false>, 144ul, 8ul> >::_M_allocate_buckets(unsigned long) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| ->05.76% (47,738,776B) 0x7D7538: std::_Hashtable<COutPoint, std::pair<COutPoint const, CCoinsCacheEntry>, PoolAllocator<std::pair<COutPoint const, CCoinsCacheEntry>, 144ul, 8ul>, std::__detail::_Select1st, std::equal_to<COutPoint>, SaltedOutpointHasher, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<false, false, true> >::_M_insert_unique_node(unsigned long, unsigned long, std::__detail::_Hash_node<std::pair<COutPoint const, CCoinsCacheEntry>, false>*, unsigned long) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|   ->05.76% (47,738,776B) 0x7D5FB7: CCoinsViewCache::BatchWrite(CoinsViewCacheCursor&, uint256 const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|   | ->05.76% (47,738,776B) 0x7D4C15: CCoinsViewCache::Flush() (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|   |   ->05.76% (47,738,776B) 0x528158: Chainstate::ConnectTip(BlockValidationState&, CBlockIndex*, std::shared_ptr<CBlock const> const&, ConnectTrace&, DisconnectedBlockTransactions&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|   |     ->05.76% (47,738,776B) 0x52E7C5: Chainstate::ActivateBestChainStep(BlockValidationState&, CBlockIndex*, std::shared_ptr<CBlock const> const&, bool&, ConnectTrace&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|   |       ->05.76% (47,738,776B) 0x52EEA3: Chainstate::ActivateBestChain(BlockValidationState&, std::shared_ptr<CBlock const>) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|   |         ->05.76% (47,738,776B) 0x30AD44: node::ImportBlocks(ChainstateManager&, std::span<fs::path const, 18446744073709551615ul>) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|   |           ->05.76% (47,738,776B) 0x27800F: std::_Function_handler<void (), AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::{lambda()
|   |             ->05.76% (47,738,776B) 0x941FCE: util::TraceThread(std::basic_string_view<char, std::char_traits<char> >, std::function<void ()>) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|   |               ->05.76% (47,738,776B) 0x2669BA: std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)(std::basic_string_view<char, std::char_traits<char> >, std::function<void ()>), char const*, AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::{lambda()
|   |                 ->05.76% (47,738,776B) 0x4B11DB3: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.33)
|   |                   ->05.76% (47,738,776B) 0x4E56AA3: start_thread (pthread_create.c:447)
|   |                     ->05.76% (47,738,776B) 0x4EE3A33: clone (clone.S:100)
|   |
|   ->00.00% (0B) in 1+ places, all below ms_print's threshold (01.00%)
|
->04.05% (33,554,432B) 0x5534C0: std::vector<uint256, std::allocator<uint256> >::_M_default_append(unsigned long) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| ->02.02% (16,777,216B) 0x539B7D: ValidationCache::ValidationCache(unsigned long, unsigned long) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | ->02.02% (16,777,216B) 0x53AC8C: ChainstateManager::ChainstateManager(util::SignalInterrupt const&, kernel::ChainstateManagerOpts, kernel::BlockManagerOpts) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |   ->02.02% (16,777,216B) 0x272139: InitAndLoadChainstate(node::NodeContext&, bool, bool, kernel::CacheSizes const&, ArgsManager const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |     ->02.02% (16,777,216B) 0x27BDAF: AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |       ->02.02% (16,777,216B) 0x23CB15: main (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |
| ->02.02% (16,777,216B) 0x5ECCC1: SignatureCache::SignatureCache(unsigned long) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|   ->02.02% (16,777,216B) 0x5398DD: ValidationCache::ValidationCache(unsigned long, unsigned long) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|     ->02.02% (16,777,216B) 0x53AC8C: ChainstateManager::ChainstateManager(util::SignalInterrupt const&, kernel::ChainstateManagerOpts, kernel::BlockManagerOpts) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|       ->02.02% (16,777,216B) 0x272139: InitAndLoadChainstate(node::NodeContext&, bool, bool, kernel::CacheSizes const&, ArgsManager const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|         ->02.02% (16,777,216B) 0x27BDAF: AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|           ->02.02% (16,777,216B) 0x23CB15: main (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|
->03.27% (27,059,600B) 0x522D80: Chainstate::TryAddBlockIndexCandidate(CBlockIndex*) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| ->03.27% (27,059,600B) 0x52483A: ChainstateManager::LoadBlockIndex() (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|   ->03.27% (27,059,600B) 0x320D97: node::CompleteChainstateInitialization(ChainstateManager&, node::ChainstateLoadOptions const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|     ->03.27% (27,059,600B) 0x321F52: node::LoadChainstate(ChainstateManager&, kernel::CacheSizes const&, node::ChainstateLoadOptions const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|       ->03.27% (27,059,600B) 0x2726C4: InitAndLoadChainstate(node::NodeContext&, bool, bool, kernel::CacheSizes const&, ArgsManager const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|         ->03.27% (27,059,600B) 0x27BDAF: AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|           ->03.27% (27,059,600B) 0x23CB15: main (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|
->02.74% (22,680,870B) 0x262882: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_mutate(unsigned long, unsigned long, char const*, unsigned long) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| ->02.66% (22,020,097B) 0x7BA029: leveldb::PutLengthPrefixedSlice(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*, leveldb::Slice const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | ->02.66% (22,020,097B) 0x7AE875: leveldb::WriteBatch::Put(leveldb::Slice const&, leveldb::Slice const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | | ->02.66% (22,020,097B) 0x5965CD: CDBBatch::WriteImpl(std::span<std::byte const, 18446744073709551615ul>, DataStream&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | |   ->02.66% (22,020,097B) 0x4DE258: CCoinsViewDB::BatchWrite(CoinsViewCacheCursor&, uint256 const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | |   | ->02.66% (22,020,097B) 0x7D4C15: CCoinsViewCache::Flush() (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | |   |   ->02.66% (22,020,097B) 0x525634: Chainstate::FlushStateToDisk(BlockValidationState&, FlushStateMode, int) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | |   |     ->02.66% (22,020,097B) 0x5283D7: Chainstate::ConnectTip(BlockValidationState&, CBlockIndex*, std::shared_ptr<CBlock const> const&, ConnectTrace&, DisconnectedBlockTransactions&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | |   |       ->02.66% (22,020,097B) 0x52E7C5: Chainstate::ActivateBestChainStep(BlockValidationState&, CBlockIndex*, std::shared_ptr<CBlock const> const&, bool&, ConnectTrace&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | |   |         ->02.66% (22,020,097B) 0x52EEA3: Chainstate::ActivateBestChain(BlockValidationState&, std::shared_ptr<CBlock const>) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | |   |           ->02.66% (22,020,097B) 0x30AD44: node::ImportBlocks(ChainstateManager&, std::span<fs::path const, 18446744073709551615ul>) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | |   |             ->02.66% (22,020,097B) 0x27800F: std::_Function_handler<void (), AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::{lambda()
| | |   |               ->02.66% (22,020,097B) 0x941FCE: util::TraceThread(std::basic_string_view<char, std::char_traits<char> >, std::function<void ()>) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | |   |                 ->02.66% (22,020,097B) 0x2669BA: std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)(std::basic_string_view<char, std::char_traits<char> >, std::function<void ()>), char const*, AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::{lambda()
| | |   |                   ->02.66% (22,020,097B) 0x4B11DB3: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.33)
| | |   |                     ->02.66% (22,020,097B) 0x4E56AA3: start_thread (pthread_create.c:447)
| | |   |                       ->02.66% (22,020,097B) 0x4EE3A33: clone (clone.S:100)
| | |   |
| | |   ->00.00% (0B) in 1+ places, all below ms_print's threshold (01.00%)
| | |
| | ->00.00% (0B) in 1+ places, all below ms_print's threshold (01.00%)
| |
| ->00.08% (660,773B) in 1+ places, all below ms_print's threshold (01.00%)
|
->01.75% (14,502,982B) in 1391 places, all below massif's threshold (1.00%)
|
->01.40% (11,577,224B) 0x31C9A9: std::_Hashtable<uint256, std::pair<uint256 const, CBlockIndex>, std::allocator<std::pair<uint256 const, CBlockIndex> >, std::__detail::_Select1st, std::equal_to<uint256>, BlockHasher, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, false, true> >::_M_insert_unique_node(unsigned long, unsigned long, std::__detail::_Hash_node<std::pair<uint256 const, CBlockIndex>, true>*, unsigned long) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
  ->01.40% (11,577,224B) 0x30D5ED: node::BlockManager::InsertBlockIndex(uint256 const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
    ->01.40% (11,577,224B) 0x311503: kernel::BlockTreeDB::LoadBlockIndexGuts(Consensus::Params const&, std::function<CBlockIndex* (uint256 const&)>, util::SignalInterrupt const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
    | ->01.40% (11,577,224B) 0x311900: node::BlockManager::LoadBlockIndex(std::optional<uint256> const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
    |   ->01.40% (11,577,224B) 0x31238C: node::BlockManager::LoadBlockIndexDB(std::optional<uint256> const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
    |     ->01.40% (11,577,224B) 0x52449F: ChainstateManager::LoadBlockIndex() (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
    |       ->01.40% (11,577,224B) 0x320D97: node::CompleteChainstateInitialization(ChainstateManager&, node::ChainstateLoadOptions const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
    |         ->01.40% (11,577,224B) 0x321F52: node::LoadChainstate(ChainstateManager&, kernel::CacheSizes const&, node::ChainstateLoadOptions const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
    |           ->01.40% (11,577,224B) 0x2726C4: InitAndLoadChainstate(node::NodeContext&, bool, bool, kernel::CacheSizes const&, ArgsManager const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
    |             ->01.40% (11,577,224B) 0x27BDAF: AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
    |               ->01.40% (11,577,224B) 0x23CB15: main (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
    |
    ->00.00% (0B) in 1+ places, all below ms_print's threshold (01.00%)
4228018 - 371,195,904B for nodes + 47,738,776B for buckets = ~400MiB dbcache usage
->47.01% (371,195,904B) 0x7D4622: std::__detail::_Hash_node<std::pair<COutPoint const, CCoinsCacheEntry>, false>* std::__detail::_Hashtable_alloc<PoolAllocator<std::__detail::_Hash_node<std::pair<COutPoint const, CCoinsCacheEntry>, false>, 144ul, 8ul> >::_M_allocate_node<std::piecewise_construct_t const&, std::tuple<COutPoint const&>, std::tuple<> >(std::piecewise_construct_t const&, std::tuple<COutPoint const&>&&, std::tuple<>&&) [clone .isra.0] (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| ->30.41% (240,123,904B) 0x7D54C2: CCoinsViewCache::FetchCoin(COutPoint const&) const (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | ->30.41% (240,123,904B) 0x7D5589: CCoinsViewCache::GetCoin(COutPoint const&) const (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | | ->30.41% (240,123,904B) 0x7D53BA: CCoinsViewCache::FetchCoin(COutPoint const&) const (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | |   ->30.41% (240,123,904B) 0x7D58BA: CCoinsViewCache::HaveInputs(CTransaction const&) const (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | |   | ->30.41% (240,123,904B) 0x594022: Consensus::CheckTxInputs(CTransaction const&, TxValidationState&, CCoinsViewCache const&, int, long&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | |   |   ->30.41% (240,123,904B) 0x518DB3: Chainstate::ConnectBlock(CBlock const&, BlockValidationState&, CBlockIndex*, CCoinsViewCache&, bool) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | |   |     ->30.41% (240,123,904B) 0x527F08: Chainstate::ConnectTip(BlockValidationState&, CBlockIndex*, std::shared_ptr<CBlock const> const&, ConnectTrace&, DisconnectedBlockTransactions&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | |   |       ->30.41% (240,123,904B) 0x52EA05: Chainstate::ActivateBestChainStep(BlockValidationState&, CBlockIndex*, std::shared_ptr<CBlock const> const&, bool&, ConnectTrace&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | |   |         ->30.41% (240,123,904B) 0x52F0E3: Chainstate::ActivateBestChain(BlockValidationState&, std::shared_ptr<CBlock const>) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | |   |           ->30.41% (240,123,904B) 0x30AE04: node::ImportBlocks(ChainstateManager&, std::span<fs::path const, 18446744073709551615ul>) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | |   |             ->30.41% (240,123,904B) 0x27804F: std::_Function_handler<void (), AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::{lambda()
| | |   |               ->30.41% (240,123,904B) 0x94234E: util::TraceThread(std::basic_string_view<char, std::char_traits<char> >, std::function<void ()>) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | |   |                 ->30.41% (240,123,904B) 0x2669FA: std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)(std::basic_string_view<char, std::char_traits<char> >, std::function<void ()>), char const*, AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::{lambda()
| | |   |                   ->30.41% (240,123,904B) 0x4B11DB3: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.33)
| | |   |                     ->30.41% (240,123,904B) 0x4E56AA3: start_thread (pthread_create.c:447)
| | |   |                       ->30.41% (240,123,904B) 0x4EE3A33: clone (clone.S:100)
| | |   |
| | |   ->00.00% (0B) in 1+ places, all below ms_print's threshold (01.00%)
| | |
| | ->00.00% (0B) in 1+ places, all below ms_print's threshold (01.00%)
| |
| ->16.60% (131,072,000B) 0x7D632B: CCoinsViewCache::BatchWrite(CoinsViewCacheCursor&, uint256 const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | ->16.60% (131,072,000B) 0x7D4FB5: CCoinsViewCache::Flush() (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |   ->16.60% (131,072,000B) 0x528398: Chainstate::ConnectTip(BlockValidationState&, CBlockIndex*, std::shared_ptr<CBlock const> const&, ConnectTrace&, DisconnectedBlockTransactions&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |     ->16.60% (131,072,000B) 0x52EA05: Chainstate::ActivateBestChainStep(BlockValidationState&, CBlockIndex*, std::shared_ptr<CBlock const> const&, bool&, ConnectTrace&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |       ->16.60% (131,072,000B) 0x52F0E3: Chainstate::ActivateBestChain(BlockValidationState&, std::shared_ptr<CBlock const>) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |         ->16.60% (131,072,000B) 0x30AE04: node::ImportBlocks(ChainstateManager&, std::span<fs::path const, 18446744073709551615ul>) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |           ->16.60% (131,072,000B) 0x27804F: std::_Function_handler<void (), AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::{lambda()
| |             ->16.60% (131,072,000B) 0x94234E: util::TraceThread(std::basic_string_view<char, std::char_traits<char> >, std::function<void ()>) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |               ->16.60% (131,072,000B) 0x2669FA: std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)(std::basic_string_view<char, std::char_traits<char> >, std::function<void ()>), char const*, AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::{lambda()
| |                 ->16.60% (131,072,000B) 0x4B11DB3: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.33)
| |                   ->16.60% (131,072,000B) 0x4E56AA3: start_thread (pthread_create.c:447)
| |                     ->16.60% (131,072,000B) 0x4EE3A33: clone (clone.S:100)
| |
| ->00.00% (0B) in 1+ places, all below ms_print's threshold (01.00%)
|
->22.74% (179,561,400B) 0x30D669: node::BlockManager::InsertBlockIndex(uint256 const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| ->11.38% (89,842,600B) 0x3115A9: kernel::BlockTreeDB::LoadBlockIndexGuts(Consensus::Params const&, std::function<CBlockIndex* (uint256 const&)>, util::SignalInterrupt const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | ->11.38% (89,842,600B) 0x3119C0: node::BlockManager::LoadBlockIndex(std::optional<uint256> const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |   ->11.38% (89,842,600B) 0x31244C: node::BlockManager::LoadBlockIndexDB(std::optional<uint256> const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |     ->11.38% (89,842,600B) 0x5246DF: ChainstateManager::LoadBlockIndex() (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |       ->11.38% (89,842,600B) 0x320E57: node::CompleteChainstateInitialization(ChainstateManager&, node::ChainstateLoadOptions const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |         ->11.38% (89,842,600B) 0x322012: node::LoadChainstate(ChainstateManager&, kernel::CacheSizes const&, node::ChainstateLoadOptions const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |           ->11.38% (89,842,600B) 0x272704: InitAndLoadChainstate(node::NodeContext&, bool, bool, kernel::CacheSizes const&, ArgsManager const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |             ->11.38% (89,842,600B) 0x27BDEF: AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |               ->11.38% (89,842,600B) 0x23CB55: main (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |
| ->11.36% (89,718,800B) 0x3115C3: kernel::BlockTreeDB::LoadBlockIndexGuts(Consensus::Params const&, std::function<CBlockIndex* (uint256 const&)>, util::SignalInterrupt const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|   ->11.36% (89,718,800B) 0x3119C0: node::BlockManager::LoadBlockIndex(std::optional<uint256> const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|     ->11.36% (89,718,800B) 0x31244C: node::BlockManager::LoadBlockIndexDB(std::optional<uint256> const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|       ->11.36% (89,718,800B) 0x5246DF: ChainstateManager::LoadBlockIndex() (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|         ->11.36% (89,718,800B) 0x320E57: node::CompleteChainstateInitialization(ChainstateManager&, node::ChainstateLoadOptions const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|           ->11.36% (89,718,800B) 0x322012: node::LoadChainstate(ChainstateManager&, kernel::CacheSizes const&, node::ChainstateLoadOptions const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|             ->11.36% (89,718,800B) 0x272704: InitAndLoadChainstate(node::NodeContext&, bool, bool, kernel::CacheSizes const&, ArgsManager const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|               ->11.36% (89,718,800B) 0x27BDEF: AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|                 ->11.36% (89,718,800B) 0x23CB55: main (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|
->07.13% (56,274,944B) 0x7B7CAD: leveldb::Arena::AllocateNewBlock(unsigned long) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| ->07.13% (56,274,944B) 0x7B7E10: leveldb::Arena::AllocateFallback(unsigned long) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | ->05.34% (42,160,128B) 0x79D1A0: leveldb::MemTable::Add(unsigned long, leveldb::ValueType, leveldb::Slice const&, leveldb::Slice const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | | ->03.32% (26,202,112B) 0x7AE96A: leveldb::WriteBatch::Iterate(leveldb::WriteBatch::Handler*) const (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | | | ->03.32% (26,202,112B) 0x7AEF24: leveldb::WriteBatchInternal::InsertInto(leveldb::WriteBatch const*, leveldb::MemTable*) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | | |   ->03.32% (26,202,112B) 0x78AE7F: leveldb::DBImpl::Write(leveldb::WriteOptions const&, leveldb::WriteBatch*) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | | |     ->03.32% (26,202,112B) 0x59734D: CDBWrapper::WriteBatch(CDBBatch&, bool) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | | |       ->03.32% (26,202,112B) 0x4DE55F: CCoinsViewDB::BatchWrite(CoinsViewCacheCursor&, uint256 const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | | |       | ->03.32% (26,202,112B) 0x7D4FB5: CCoinsViewCache::Flush() (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | | |       |   ->03.32% (26,202,112B) 0x525874: Chainstate::FlushStateToDisk(BlockValidationState&, FlushStateMode, int) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | | |       |     ->03.32% (26,202,112B) 0x528617: Chainstate::ConnectTip(BlockValidationState&, CBlockIndex*, std::shared_ptr<CBlock const> const&, ConnectTrace&, DisconnectedBlockTransactions&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | | |       |       ->03.32% (26,202,112B) 0x52EA05: Chainstate::ActivateBestChainStep(BlockValidationState&, CBlockIndex*, std::shared_ptr<CBlock const> const&, bool&, ConnectTrace&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | | |       |         ->03.32% (26,202,112B) 0x52F0E3: Chainstate::ActivateBestChain(BlockValidationState&, std::shared_ptr<CBlock const>) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | | |       |           ->03.32% (26,202,112B) 0x30AE04: node::ImportBlocks(ChainstateManager&, std::span<fs::path const, 18446744073709551615ul>) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | | |       |             ->03.32% (26,202,112B) 0x27804F: std::_Function_handler<void (), AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::{lambda()
| | | |       |               ->03.32% (26,202,112B) 0x94234E: util::TraceThread(std::basic_string_view<char, std::char_traits<char> >, std::function<void ()>) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | | |       |                 ->03.32% (26,202,112B) 0x2669FA: std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)(std::basic_string_view<char, std::char_traits<char> >, std::function<void ()>), char const*, AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::{lambda()
| | | |       |                   ->03.32% (26,202,112B) 0x4B11DB3: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.33)
| | | |       |                     ->03.32% (26,202,112B) 0x4E56AA3: start_thread (pthread_create.c:447)
| | | |       |                       ->03.32% (26,202,112B) 0x4EE3A33: clone (clone.S:100)
| | | |       |
| | | |       ->00.00% (0B) in 1+ places, all below ms_print's threshold (01.00%)
| | | |
| | | ->02.02% (15,958,016B) 0x7AE893: leveldb::WriteBatch::Iterate(leveldb::WriteBatch::Handler*) const (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | |   ->02.02% (15,958,016B) 0x7AEF24: leveldb::WriteBatchInternal::InsertInto(leveldb::WriteBatch const*, leveldb::MemTable*) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | |     ->02.02% (15,958,016B) 0x78AE7F: leveldb::DBImpl::Write(leveldb::WriteOptions const&, leveldb::WriteBatch*) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | |       ->02.02% (15,958,016B) 0x59734D: CDBWrapper::WriteBatch(CDBBatch&, bool) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | |         ->02.02% (15,953,920B) 0x4DE55F: CCoinsViewDB::BatchWrite(CoinsViewCacheCursor&, uint256 const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | |         | ->02.02% (15,953,920B) 0x7D4FB5: CCoinsViewCache::Flush() (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | |         |   ->02.02% (15,953,920B) 0x525874: Chainstate::FlushStateToDisk(BlockValidationState&, FlushStateMode, int) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | |         |     ->02.02% (15,953,920B) 0x528617: Chainstate::ConnectTip(BlockValidationState&, CBlockIndex*, std::shared_ptr<CBlock const> const&, ConnectTrace&, DisconnectedBlockTransactions&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | |         |       ->02.02% (15,953,920B) 0x52EA05: Chainstate::ActivateBestChainStep(BlockValidationState&, CBlockIndex*, std::shared_ptr<CBlock const> const&, bool&, ConnectTrace&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | |         |         ->02.02% (15,953,920B) 0x52F0E3: Chainstate::ActivateBestChain(BlockValidationState&, std::shared_ptr<CBlock const>) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | |         |           ->02.02% (15,953,920B) 0x30AE04: node::ImportBlocks(ChainstateManager&, std::span<fs::path const, 18446744073709551615ul>) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | |         |             ->02.02% (15,953,920B) 0x27804F: std::_Function_handler<void (), AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::{lambda()
| | |         |               ->02.02% (15,953,920B) 0x94234E: util::TraceThread(std::basic_string_view<char, std::char_traits<char> >, std::function<void ()>) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | |         |                 ->02.02% (15,953,920B) 0x2669FA: std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)(std::basic_string_view<char, std::char_traits<char> >, std::function<void ()>), char const*, AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::{lambda()
| | |         |                   ->02.02% (15,953,920B) 0x4B11DB3: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.33)
| | |         |                     ->02.02% (15,953,920B) 0x4E56AA3: start_thread (pthread_create.c:447)
| | |         |                       ->02.02% (15,953,920B) 0x4EE3A33: clone (clone.S:100)
| | |         |
| | |         ->00.00% (4,096B) in 1+ places, all below ms_print's threshold (01.00%)
| | |
| | ->01.79% (14,114,816B) 0x7B7EDC: leveldb::Arena::AllocateAligned(unsigned long) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |   ->01.79% (14,102,528B) 0x79DB59: leveldb::SkipList<char const*, leveldb::MemTable::KeyComparator>::Insert(char const* const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |   | ->01.79% (14,102,528B) 0x79D16B: leveldb::MemTable::Add(unsigned long, leveldb::ValueType, leveldb::Slice const&, leveldb::Slice const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |   |   ->01.28% (10,133,504B) 0x7AE96A: leveldb::WriteBatch::Iterate(leveldb::WriteBatch::Handler*) const (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |   |   | ->01.28% (10,133,504B) 0x7AEF24: leveldb::WriteBatchInternal::InsertInto(leveldb::WriteBatch const*, leveldb::MemTable*) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |   |   |   ->01.28% (10,133,504B) 0x78AE7F: leveldb::DBImpl::Write(leveldb::WriteOptions const&, leveldb::WriteBatch*) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |   |   |     ->01.28% (10,133,504B) 0x59734D: CDBWrapper::WriteBatch(CDBBatch&, bool) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |   |   |       ->01.28% (10,133,504B) 0x4DE55F: CCoinsViewDB::BatchWrite(CoinsViewCacheCursor&, uint256 const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |   |   |       | ->01.28% (10,133,504B) 0x7D4FB5: CCoinsViewCache::Flush() (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |   |   |       |   ->01.28% (10,133,504B) 0x525874: Chainstate::FlushStateToDisk(BlockValidationState&, FlushStateMode, int) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |   |   |       |     ->01.28% (10,133,504B) 0x528617: Chainstate::ConnectTip(BlockValidationState&, CBlockIndex*, std::shared_ptr<CBlock const> const&, ConnectTrace&, DisconnectedBlockTransactions&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |   |   |       |       ->01.28% (10,133,504B) 0x52EA05: Chainstate::ActivateBestChainStep(BlockValidationState&, CBlockIndex*, std::shared_ptr<CBlock const> const&, bool&, ConnectTrace&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |   |   |       |         ->01.28% (10,133,504B) 0x52F0E3: Chainstate::ActivateBestChain(BlockValidationState&, std::shared_ptr<CBlock const>) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |   |   |       |           ->01.28% (10,133,504B) 0x30AE04: node::ImportBlocks(ChainstateManager&, std::span<fs::path const, 18446744073709551615ul>) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |   |   |       |             ->01.28% (10,133,504B) 0x27804F: std::_Function_handler<void (), AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::{lambda()
| |   |   |       |               ->01.28% (10,133,504B) 0x94234E: util::TraceThread(std::basic_string_view<char, std::char_traits<char> >, std::function<void ()>) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |   |   |       |                 ->01.28% (10,133,504B) 0x2669FA: std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)(std::basic_string_view<char, std::char_traits<char> >, std::function<void ()>), char const*, AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::{lambda()
| |   |   |       |                   ->01.28% (10,133,504B) 0x4B11DB3: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.33)
| |   |   |       |                     ->01.28% (10,133,504B) 0x4E56AA3: start_thread (pthread_create.c:447)
| |   |   |       |                       ->01.28% (10,133,504B) 0x4EE3A33: clone (clone.S:100)
| |   |   |       |
| |   |   |       ->00.00% (0B) in 1+ places, all below ms_print's threshold (01.00%)
| |   |   |
| |   |   ->00.50% (3,969,024B) in 1+ places, all below ms_print's threshold (01.00%)
| |   |
| |   ->00.00% (12,288B) in 1+ places, all below ms_print's threshold (01.00%)
| |
| ->00.00% (0B) in 1+ places, all below ms_print's threshold (01.00%)
|
->06.05% (47,738,776B) 0x7D76AC: std::__detail::_Hashtable_alloc<PoolAllocator<std::__detail::_Hash_node<std::pair<COutPoint const, CCoinsCacheEntry>, false>, 144ul, 8ul> >::_M_allocate_buckets(unsigned long) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| ->06.05% (47,738,776B) 0x7D78D8: std::_Hashtable<COutPoint, std::pair<COutPoint const, CCoinsCacheEntry>, PoolAllocator<std::pair<COutPoint const, CCoinsCacheEntry>, 144ul, 8ul>, std::__detail::_Select1st, std::equal_to<COutPoint>, SaltedOutpointHasher, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<false, false, true> >::_M_insert_unique_node(unsigned long, unsigned long, std::__detail::_Hash_node<std::pair<COutPoint const, CCoinsCacheEntry>, false>*, unsigned long) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|   ->06.05% (47,738,776B) 0x7D54DE: CCoinsViewCache::FetchCoin(COutPoint const&) const (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|   | ->06.05% (47,738,776B) 0x7D5589: CCoinsViewCache::GetCoin(COutPoint const&) const (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|   | | ->06.05% (47,738,776B) 0x7D53BA: CCoinsViewCache::FetchCoin(COutPoint const&) const (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|   | |   ->06.05% (47,738,776B) 0x7D58BA: CCoinsViewCache::HaveInputs(CTransaction const&) const (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|   | |   | ->06.05% (47,738,776B) 0x594022: Consensus::CheckTxInputs(CTransaction const&, TxValidationState&, CCoinsViewCache const&, int, long&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|   | |   |   ->06.05% (47,738,776B) 0x518DB3: Chainstate::ConnectBlock(CBlock const&, BlockValidationState&, CBlockIndex*, CCoinsViewCache&, bool) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|   | |   |     ->06.05% (47,738,776B) 0x527F08: Chainstate::ConnectTip(BlockValidationState&, CBlockIndex*, std::shared_ptr<CBlock const> const&, ConnectTrace&, DisconnectedBlockTransactions&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|   | |   |       ->06.05% (47,738,776B) 0x52EA05: Chainstate::ActivateBestChainStep(BlockValidationState&, CBlockIndex*, std::shared_ptr<CBlock const> const&, bool&, ConnectTrace&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|   | |   |         ->06.05% (47,738,776B) 0x52F0E3: Chainstate::ActivateBestChain(BlockValidationState&, std::shared_ptr<CBlock const>) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|   | |   |           ->06.05% (47,738,776B) 0x30AE04: node::ImportBlocks(ChainstateManager&, std::span<fs::path const, 18446744073709551615ul>) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|   | |   |             ->06.05% (47,738,776B) 0x27804F: std::_Function_handler<void (), AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::{lambda()
|   | |   |               ->06.05% (47,738,776B) 0x94234E: util::TraceThread(std::basic_string_view<char, std::char_traits<char> >, std::function<void ()>) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|   | |   |                 ->06.05% (47,738,776B) 0x2669FA: std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)(std::basic_string_view<char, std::char_traits<char> >, std::function<void ()>), char const*, AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::{lambda()
|   | |   |                   ->06.05% (47,738,776B) 0x4B11DB3: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.33)
|   | |   |                     ->06.05% (47,738,776B) 0x4E56AA3: start_thread (pthread_create.c:447)
|   | |   |                       ->06.05% (47,738,776B) 0x4EE3A33: clone (clone.S:100)
|   | |   |
|   | |   ->00.00% (0B) in 1+ places, all below ms_print's threshold (01.00%)
|   | |
|   | ->00.00% (0B) in 1+ places, all below ms_print's threshold (01.00%)
|   |
|   ->00.00% (0B) in 1+ places, all below ms_print's threshold (01.00%)
|
->04.25% (33,554,432B) 0x553700: std::vector<uint256, std::allocator<uint256> >::_M_default_append(unsigned long) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| ->02.12% (16,777,216B) 0x539DBD: ValidationCache::ValidationCache(unsigned long, unsigned long) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | ->02.12% (16,777,216B) 0x53AECC: ChainstateManager::ChainstateManager(util::SignalInterrupt const&, kernel::ChainstateManagerOpts, kernel::BlockManagerOpts) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |   ->02.12% (16,777,216B) 0x272179: InitAndLoadChainstate(node::NodeContext&, bool, bool, kernel::CacheSizes const&, ArgsManager const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |     ->02.12% (16,777,216B) 0x27BDEF: AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |       ->02.12% (16,777,216B) 0x23CB55: main (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| |
| ->02.12% (16,777,216B) 0x5ED041: SignatureCache::SignatureCache(unsigned long) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|   ->02.12% (16,777,216B) 0x539B1D: ValidationCache::ValidationCache(unsigned long, unsigned long) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|     ->02.12% (16,777,216B) 0x53AECC: ChainstateManager::ChainstateManager(util::SignalInterrupt const&, kernel::ChainstateManagerOpts, kernel::BlockManagerOpts) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|       ->02.12% (16,777,216B) 0x272179: InitAndLoadChainstate(node::NodeContext&, bool, bool, kernel::CacheSizes const&, ArgsManager const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|         ->02.12% (16,777,216B) 0x27BDEF: AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|           ->02.12% (16,777,216B) 0x23CB55: main (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|
->02.94% (23,223,062B) 0x2628C2: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_mutate(unsigned long, unsigned long, char const*, unsigned long) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| ->02.79% (22,020,097B) 0x7BA3A9: leveldb::PutLengthPrefixedSlice(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*, leveldb::Slice const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | ->02.79% (22,020,097B) 0x59680D: CDBBatch::WriteImpl(std::span<std::byte const, 18446744073709551615ul>, DataStream&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | | ->02.79% (22,020,097B) 0x4DE3D8: CCoinsViewDB::BatchWrite(CoinsViewCacheCursor&, uint256 const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | | | ->02.79% (22,020,097B) 0x7D4FB5: CCoinsViewCache::Flush() (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | | |   ->02.79% (22,020,097B) 0x525874: Chainstate::FlushStateToDisk(BlockValidationState&, FlushStateMode, int) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | | |     ->02.79% (22,020,097B) 0x528617: Chainstate::ConnectTip(BlockValidationState&, CBlockIndex*, std::shared_ptr<CBlock const> const&, ConnectTrace&, DisconnectedBlockTransactions&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | | |       ->02.79% (22,020,097B) 0x52EA05: Chainstate::ActivateBestChainStep(BlockValidationState&, CBlockIndex*, std::shared_ptr<CBlock const> const&, bool&, ConnectTrace&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | | |         ->02.79% (22,020,097B) 0x52F0E3: Chainstate::ActivateBestChain(BlockValidationState&, std::shared_ptr<CBlock const>) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | | |           ->02.79% (22,020,097B) 0x30AE04: node::ImportBlocks(ChainstateManager&, std::span<fs::path const, 18446744073709551615ul>) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | | |             ->02.79% (22,020,097B) 0x27804F: std::_Function_handler<void (), AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::{lambda()
| | | |               ->02.79% (22,020,097B) 0x94234E: util::TraceThread(std::basic_string_view<char, std::char_traits<char> >, std::function<void ()>) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| | | |                 ->02.79% (22,020,097B) 0x2669FA: std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)(std::basic_string_view<char, std::char_traits<char> >, std::function<void ()>), char const*, AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::{lambda()
| | | |                   ->02.79% (22,020,097B) 0x4B11DB3: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.33)
| | | |                     ->02.79% (22,020,097B) 0x4E56AA3: start_thread (pthread_create.c:447)
| | | |                       ->02.79% (22,020,097B) 0x4EE3A33: clone (clone.S:100)
| | | |
| | | ->00.00% (0B) in 1+ places, all below ms_print's threshold (01.00%)
| | |
| | ->00.00% (0B) in 1+ places, all below ms_print's threshold (01.00%)
| |
| ->00.15% (1,202,965B) in 1+ places, all below ms_print's threshold (01.00%)
|
->02.63% (20,761,810B) in 1447 places, all below massif's threshold (1.00%)
|
->01.81% (14,280,200B) 0x522FC0: Chainstate::TryAddBlockIndexCandidate(CBlockIndex*) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| ->01.81% (14,280,200B) 0x524A7A: ChainstateManager::LoadBlockIndex() (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|   ->01.81% (14,280,200B) 0x320E57: node::CompleteChainstateInitialization(ChainstateManager&, node::ChainstateLoadOptions const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|     ->01.81% (14,280,200B) 0x322012: node::LoadChainstate(ChainstateManager&, kernel::CacheSizes const&, node::ChainstateLoadOptions const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|       ->01.81% (14,280,200B) 0x272704: InitAndLoadChainstate(node::NodeContext&, bool, bool, kernel::CacheSizes const&, ArgsManager const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|         ->01.81% (14,280,200B) 0x27BDEF: AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|           ->01.81% (14,280,200B) 0x23CB55: main (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|
->01.47% (11,577,224B) 0x31CA69: std::_Hashtable<uint256, std::pair<uint256 const, CBlockIndex>, std::allocator<std::pair<uint256 const, CBlockIndex> >, std::__detail::_Select1st, std::equal_to<uint256>, BlockHasher, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, false, true> >::_M_insert_unique_node(unsigned long, unsigned long, std::__detail::_Hash_node<std::pair<uint256 const, CBlockIndex>, true>*, unsigned long) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
| ->01.47% (11,577,224B) 0x30D6AD: node::BlockManager::InsertBlockIndex(uint256 const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|   ->01.47% (11,577,224B) 0x3115C3: kernel::BlockTreeDB::LoadBlockIndexGuts(Consensus::Params const&, std::function<CBlockIndex* (uint256 const&)>, util::SignalInterrupt const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|   | ->01.47% (11,577,224B) 0x3119C0: node::BlockManager::LoadBlockIndex(std::optional<uint256> const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|   |   ->01.47% (11,577,224B) 0x31244C: node::BlockManager::LoadBlockIndexDB(std::optional<uint256> const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|   |     ->01.47% (11,577,224B) 0x5246DF: ChainstateManager::LoadBlockIndex() (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|   |       ->01.47% (11,577,224B) 0x320E57: node::CompleteChainstateInitialization(ChainstateManager&, node::ChainstateLoadOptions const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|   |         ->01.47% (11,577,224B) 0x322012: node::LoadChainstate(ChainstateManager&, kernel::CacheSizes const&, node::ChainstateLoadOptions const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|   |           ->01.47% (11,577,224B) 0x272704: InitAndLoadChainstate(node::NodeContext&, bool, bool, kernel::CacheSizes const&, ArgsManager const&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|   |             ->01.47% (11,577,224B) 0x27BDEF: AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|   |               ->01.47% (11,577,224B) 0x23CB55: main (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
|   |
|   ->00.00% (0B) in 1+ places, all below ms_print's threshold (01.00%)
|
->01.06% (8,388,608B) 0x7CFA4D: std::vector<CBlockIndex*, std::allocator<CBlockIndex*> >::_M_default_append(unsigned long) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
  ->01.06% (8,388,608B) 0x7CF99A: CChain::SetTip(CBlockIndex&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
    ->01.06% (8,388,608B) 0x528699: Chainstate::ConnectTip(BlockValidationState&, CBlockIndex*, std::shared_ptr<CBlock const> const&, ConnectTrace&, DisconnectedBlockTransactions&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
      ->01.06% (8,388,608B) 0x52EA05: Chainstate::ActivateBestChainStep(BlockValidationState&, CBlockIndex*, std::shared_ptr<CBlock const> const&, bool&, ConnectTrace&) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
        ->01.06% (8,388,608B) 0x52F0E3: Chainstate::ActivateBestChain(BlockValidationState&, std::shared_ptr<CBlock const>) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
          ->01.06% (8,388,608B) 0x30AE04: node::ImportBlocks(ChainstateManager&, std::span<fs::path const, 18446744073709551615ul>) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
            ->01.06% (8,388,608B) 0x27804F: std::_Function_handler<void (), AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::{lambda()
              ->01.06% (8,388,608B) 0x94234E: util::TraceThread(std::basic_string_view<char, std::char_traits<char> >, std::function<void ()>) (in /mnt/my_storage/bitcoin/build/bin/bitcoind)
                ->01.06% (8,388,608B) 0x2669FA: std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)(std::basic_string_view<char, std::char_traits<char> >, std::function<void ()>), char const*, AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::{lambda()
                  ->01.06% (8,388,608B) 0x4B11DB3: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.33)
                    ->01.06% (8,388,608B) 0x4E56AA3: start_thread (pthread_create.c:447)
                      ->01.06% (8,388,608B) 0x4EE3A33: clone (clone.S:100)

Which reveals that the the new MallocUsage formula overestimates node allocations, allowing fewer coins in the cache.
Plotting the number of cache coins over time is also revealing:
cache_coins_vs_time

The actual memory allocated for the bucket arrays of the cache appears identical at peak times.
I found it surprising that the two measurements resulted in exactly the same bucket sizes - and how precisely master estimated the dbcache size (at least with GCC).


I would expect clang to behave slightly differently - but it takes a week to measure these, so I would like some explanations first before I spend more time re-measuring the scenarios, since it seems that MallocUsage accuracy was already surprisingly accurate.

@DrahtBot
Copy link
Contributor

DrahtBot commented Jun 7, 2025

🚧 At least one of the CI tasks failed.
Task no wallet, libbitcoinkernel: https://github.com/bitcoin/bitcoin/runs/43652579216
LLM reason (✨ experimental): The CI failure is caused by compilation errors due to compiler flags treating unused private fields as errors.

Hints

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.

Co-authored-by: Sebastian Falbesoner <sebastian.falbesoner@gmail.com>
Co-authored-by: Pieter Wuille <pieter@wuille.net>
Co-authored-by: Martin Leitner-Ankerl <martin.ankerl@gmail.com>
Co-authored-by: l0rinc <pap.lorinc@gmail.com>

# Changes to test/functional/test_framework/mempool_util.py:

## fill_mempool() should call sync_mempools() before returning

We saw a case where a test (p2p_1p1c_network.py) called
raise_network_minfee(), which called fill_mempool() using node 0.

Then raise_network_minfee() returned, and the test called rescan_utxos(),
which called getrawmempool() using a different node (node 1) followed by
getrawtransaction() on each returned transaction, and the test asserted
because a transaction was not found.

This was caused by the timing window between the call to getrawmempool()
and fetching the individual transactions; the transactions were still
being propagated on the P2P network. During this window, a transaction
(returned by getrawmempool()) was evicted (the mempool is close to full
during this test), and did not exist in the mempool by the time it was
attempted to be fetched.

It might make more sense for rescan_utxos() to call sync_mempools() just
before calling getrawmempool(), but it can't because rescan_utxos() is
part of the MiniWallet class, which doesn't have access to test_framework
(but that could probably be changed).

## ensure that `fill_mempool` leaves some room in mempool

Without this change, fill_mempool() may leave the mempool very close
to its memory size limit (-maxmempool). This can cause tests to
incorrectly fail when they submit another transaction expecting it
to succeed. Note that without this change, the same test that fails on
one platform may succeed on another, because their memory allocation
accounting algorithms (how they calculate memory usage, that is,
MallocUsage()) may be slightly different.
This commit is temporary because it makes one of the new tests fail
intentionally so we can gather some information from CI across the
platforms. (second attempt, fixes CI error private field not used)
@LarryRuane LarryRuane force-pushed the 2023-09-MallocUsage branch from b12d848 to b36b234 Compare June 8, 2025 16:17

#include <boost/test/unit_test.hpp>

BOOST_AUTO_TEST_SUITE(util_malloc_usage_tests)
Copy link
Contributor

@l0rinc l0rinc Jun 8, 2025

Choose a reason for hiding this comment

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

@LarryRuane, most of these tests will be executed on your own fork as well (except a few Cirrus fuzzers).
You can freely experiment there - see for example my attempts at l0rinc#20

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I didn't know that, that will prevent clutter here with that temporary stuff, thanks! I'll do that from now on (I want to do a few more similar experiments).

Copy link
Contributor

Choose a reason for hiding this comment

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

yeah, I also have a few experiments where I'm not sure about the state of CI so I push to my local fork first - though the remaining CIs still surprise me sometimes after upstream push :)

@sipa
Copy link
Member

sipa commented Jun 8, 2025

I wonder if perhaps it would be feasible to run a little runtime self-calibration at startup to find the malloc overhead parameters, so that they would be correct on all platforms.

It would make calls to MallocUsage much slower of course, but maybe not to such an extent that it is measurable.

@l0rinc
Copy link
Contributor

l0rinc commented Jun 10, 2025

As @LarryRuane noticed, the new address-diff test sometimes disagrees with MallocUsage on macOS and on sanitizer builds.

I had to read a bit to understand why - I never needed the gory details until now. 🙂

It seem to me that macOS's nano allocator, and the allocators used by TSan/ASan, store per-chunk metadata in shadow tables rather than inline with the user block. For example, this might be related to what we're seeing: https://github.com/aosm/libmalloc/blob/master/src/nano_malloc.c#L181.
And because the test measures only the spacing between user-visible blocks, it doesn't account for that out-of-band metadata and ends up underreporting (e.g. it sees 16 bytes used when the real usage is 24). And let's not forget that we also have a specialized PoolAllocator which we should probably include in our testing to be able to measure the main memory hog properly.

So maybe we could specialize the tests by platform/compiler/arch/OS (without duplicating MallocUsage of course) - skipping sanitizers if they still behave differently - and only checking that our estimate is never lower, and if higher, not more than a fixed or a relative amount.

I personally would avoid the runtime self-calibration path - rather abstracting away our findings and generalizing it based on self-contained test behavior sounds more predictable to me.

If we decide to keep the current settings (even though my massif memory allocation measurements (which should actually measure everything instead of just hoping that it instruments every call) do show it to be less accurate), and if we're still over-counting in the end, we can probably increase the default -dbcache slightly to adjust for the calculation difference.
That's why I'm trying to remeasure with heaptrack as well to know if it's just some bias of the tool.

@maflcko
Copy link
Member

maflcko commented Jul 18, 2025

Could turn into draft while CI is red?

@LarryRuane LarryRuane marked this pull request as draft July 18, 2025 13:10
l0rinc added a commit to l0rinc/bitcoin that referenced this pull request Jul 20, 2025
After the changes in bitcoin#25325 `getcoinscachesizestate` always end the test early, see:
https://maflcko.github.io/b-c-cov/test_bitcoin.coverage/src/test/validation_flush_tests.cpp.gcov.html

The test revival was extracted from a related PR where it was discovered, see: bitcoin#28531 (comment)

Co-authored-by: Larry Ruane <larryruane@gmail.com>
l0rinc added a commit to l0rinc/bitcoin that referenced this pull request Jul 20, 2025
After the changes in bitcoin#25325 `getcoinscachesizestate` always end the test early, see:
https://maflcko.github.io/b-c-cov/test_bitcoin.coverage/src/test/validation_flush_tests.cpp.gcov.html

The test revival was extracted from a related PR where it was discovered, see: bitcoin#28531 (comment)

Co-authored-by: Larry Ruane <larryruane@gmail.com>
l0rinc added a commit to l0rinc/bitcoin that referenced this pull request Jul 20, 2025
After the changes in bitcoin#25325 `getcoinscachesizestate` always end the test early, see:
https://maflcko.github.io/b-c-cov/test_bitcoin.coverage/src/test/validation_flush_tests.cpp.gcov.html

The test revival was extracted from a related PR where it was discovered, see: bitcoin#28531 (comment)

Co-authored-by: Larry Ruane <larryruane@gmail.com>
l0rinc added a commit to l0rinc/bitcoin that referenced this pull request Jul 20, 2025
After the changes in bitcoin#25325 `getcoinscachesizestate` always end the test early, see:
https://maflcko.github.io/b-c-cov/test_bitcoin.coverage/src/test/validation_flush_tests.cpp.gcov.html

The test revival was extracted from a related PR where it was discovered, see: bitcoin#28531 (comment)

Co-authored-by: Larry Ruane <larryruane@gmail.com>
l0rinc added a commit to l0rinc/bitcoin that referenced this pull request Jul 20, 2025
After the changes in bitcoin#25325 `getcoinscachesizestate` always end the test early, see:
https://maflcko.github.io/b-c-cov/test_bitcoin.coverage/src/test/validation_flush_tests.cpp.gcov.html

The test revival was extracted from a related PR where it was discovered, see: bitcoin#28531 (comment)

Co-authored-by: Larry Ruane <larryruane@gmail.com>
l0rinc added a commit to l0rinc/bitcoin that referenced this pull request Jul 20, 2025
After the changes in bitcoin#25325 `getcoinscachesizestate` always end the test early, see:
https://maflcko.github.io/b-c-cov/test_bitcoin.coverage/src/test/validation_flush_tests.cpp.gcov.html

The test revival was extracted from a related PR where it was discovered, see: bitcoin#28531 (comment)

Co-authored-by: Larry Ruane <larryruane@gmail.com>
l0rinc added a commit to l0rinc/bitcoin that referenced this pull request Jul 20, 2025
After the changes in bitcoin#25325 `getcoinscachesizestate` always end the test early, see:
https://maflcko.github.io/b-c-cov/test_bitcoin.coverage/src/test/validation_flush_tests.cpp.gcov.html

The test revival was extracted from a related PR where it was discovered, see: bitcoin#28531 (comment)

Co-authored-by: Larry Ruane <larryruane@gmail.com>
l0rinc added a commit to l0rinc/bitcoin that referenced this pull request Jul 28, 2025
After the changes in bitcoin#25325 `getcoinscachesizestate` always end the test early, see:
https://maflcko.github.io/b-c-cov/test_bitcoin.coverage/src/test/validation_flush_tests.cpp.gcov.html

The test revival was extracted from a related PR where it was discovered, see: bitcoin#28531 (comment)

Co-authored-by: Larry Ruane <larryruane@gmail.com>
@DrahtBot
Copy link
Contributor

🐙 This pull request conflicts with the target branch and needs rebase.

achow101 added a commit that referenced this pull request Aug 11, 2025
…eSizeState` switches from OK→LARGE→CRITICAL

554befd test: revive `getcoinscachesizestate` (Lőrinc)
64ed0fa refactor: modernize `LargeCoinsCacheThreshold` (Lőrinc)
1b40dc0 refactor: extract `LargeCoinsCacheThreshold` from `GetCoinsCacheSizeState` (Lőrinc)

Pull request description:

  After the changes in #25325 `getcoinscachesizestate` [always ended the test early](https://maflcko.github.io/b-c-cov/test_bitcoin.coverage/src/test/validation_flush_tests.cpp.gcov.html#L65):

  | File                         | Line Rate | Line Total | Line Hit | Branch Rate | Branch Total | Branch Hit |
  |------------------------------|---------:|-----------:|---------:|------------:|-------------:|-----------:|
  | validation_flush_tests.cpp   | **31.5 %**   | 54         | 17       | 22.3 %      | 242          | 54         |

  The test revival was [extracted from a related PR](#28531 (comment)) where it was [discovered](#28531 (comment)).

ACKs for top commit:
  achow101:
    ACK 554befd
  LarryRuane:
    ACK 554befd
  w0xlt:
    ACK 554befd

Tree-SHA512: f5057254de8fb3fa627dd20fee6818cfadeb2e9f629f9972059ad7b32e01fcd7dc9922eff9da2d363b36a9f0954d9bc1c4131d47b2a9c6cc348d9864953b91be
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants