Skip to content

Commit

Permalink
improve MallocUsage() accuracy
Browse files Browse the repository at this point in the history
  • Loading branch information
LarryRuane committed Sep 25, 2023
1 parent dcfbf3c commit 241766f
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 12 deletions.
1 change: 1 addition & 0 deletions src/Makefile.test.include
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ BITCOIN_TESTS =\
test/key_io_tests.cpp \
test/key_tests.cpp \
test/logging_tests.cpp \
test/malloc_usage_tests.cpp \
test/mempool_tests.cpp \
test/merkle_tests.cpp \
test/merkleblock_tests.cpp \
Expand Down
17 changes: 6 additions & 11 deletions src/memusage.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,16 +50,8 @@ template<typename X> static inline size_t DynamicUsage(const X * const &v) { ret

static inline size_t MallocUsage(size_t alloc)
{
// Measured on libc6 2.19 on Linux.
if (alloc == 0) {
return 0;
} else if (sizeof(void*) == 8) {
return ((alloc + 31) >> 4) << 4;
} else if (sizeof(void*) == 4) {
return ((alloc + 15) >> 3) << 3;
} else {
assert(0);
}
static_assert(sizeof(void*) == 4 || sizeof(void*) == 8);
return (sizeof(void*) == 8) ? std::max<size_t>(32, (alloc + 23) & ~15) : (alloc + 19) & ~15;
}

// STL data structures
Expand Down Expand Up @@ -93,7 +85,10 @@ static inline size_t DynamicUsage(const std::vector<X>& v)
template<unsigned int N, typename X, typename S, typename D>
static inline size_t DynamicUsage(const prevector<N, X, S, D>& v)
{
return MallocUsage(v.allocated_memory());
// If allocated_memory() returns zero, we haven't done an actual
// zero-byte allocation, which does require physical memory.
size_t am{v.allocated_memory()};
return am > 0 ? MallocUsage(am) : 0;
}

template<typename X, typename Y>
Expand Down
51 changes: 51 additions & 0 deletions src/test/malloc_usage_tests.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright (c) 2023 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or https://www.opensource.org/licenses/mit-license.php.

#include <memusage.h>

#include <test/util/setup_common.h>

#include <boost/test/unit_test.hpp>

BOOST_FIXTURE_TEST_SUITE(malloc_usage_tests, BasicTestingSetup)

//! Test the accuracy of MallocUsage() by noting how far the returned
//! pointer advances for each allocation; most of the time it should
//! be as predicted by MallocUsage(). Do this across various allocation
//! sizes; it's probably sufficient to not go beyond 256, because any
//! error on sizes larger than that won't be large as a fraction.
BOOST_AUTO_TEST_CASE(malloc_usage)
{
std::vector<void*> alloc_pointers;
for (size_t size{0}; size <= 256; ++size) {
void* prev_p{};
const size_t malloc_usage{memusage::MallocUsage(size)};
int accurate{0};
int inaccurate{0};
constexpr int repetitions{10000};
for (int i{0}; i < repetitions; ++i) {
void* p{malloc(size)};
alloc_pointers.push_back(p);
intptr_t p_int{intptr_t(p)};
intptr_t prev_p_int{intptr_t(prev_p)};
// Due to earlier allocations (fragmentation), allocation
// addresses can jump around; if the latest one is too
// far from the previous one, ignore it.
if (p_int > prev_p_int && p_int < prev_p_int + intptr_t(malloc_usage * 4)) {
if (size_t(p_int - prev_p_int) == malloc_usage) {
++accurate;
} else {
++inaccurate;
}
}
prev_p = p;
}
BOOST_CHECK_GT(accurate, inaccurate * 10);
}
for (void* p : alloc_pointers) {
free(p);
}
}

BOOST_AUTO_TEST_SUITE_END()
2 changes: 1 addition & 1 deletion src/test/validation_flush_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ BOOST_AUTO_TEST_CASE(getcoinscachesizestate)
// (prevector<28, unsigned char>) when assigned 56 bytes of data per above.
//
// See also: Coin::DynamicMemoryUsage().
constexpr unsigned int COIN_SIZE = is_64_bit ? 80 : 64;
constexpr size_t COIN_SIZE{64};

auto print_view_mem_usage = [](CCoinsViewCache& view) {
BOOST_TEST_MESSAGE("CCoinsViewCache memory usage: " << view.DynamicMemoryUsage());
Expand Down

0 comments on commit 241766f

Please sign in to comment.