Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix HashStringAllocator::clear() and cumulativeBytes_ #10260

Closed
wants to merge 1 commit into from

Conversation

wypb
Copy link
Contributor

@wypb wypb commented Jun 19, 2024

Summary: This PR solves the following issues:

  1. cumulativeBytes_ is the counter of allocated bytes, if we allocate n blocks and then execute free() on these blocks, the final value of cumulativeBytes_ should be equal to 0. But without this PR, the value of cumulativeBytes_ is not equal to 0. see HashStringAllocatorTest#multipleFreeAncCheckCumulativeBytes test case in this PR. This is because we don't include the size of the Header when calculating the allocated bytes.
  2. When executing HashStringAllocator::clear(), we need to decrement memory counters. PR Fix HashStringAllocator::clear #10053 only decrement memory counters when releasing allocationsFromPool_. We also need to decrement the memory counters when releasing memory requested by memory::AllocationPool.
  3. After executing HashStringAllocator::clear(), the values ​​of cumulativeBytes_ and sizeFromPool_ should be equal to 0.

CC: @xiaoxmeng @mbasmanova

@facebook-github-bot facebook-github-bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Jun 19, 2024
Copy link

netlify bot commented Jun 19, 2024

Deploy Preview for meta-velox canceled.

Name Link
🔨 Latest commit 6d2b30e
🔍 Latest deploy log https://app.netlify.com/sites/meta-velox/deploys/667d0bd96b59ee00083891b0

@wypb wypb force-pushed the fix_HashStringAllocator branch from 16f6ff9 to 3eaa100 Compare June 19, 2024 08:12
@wypb wypb changed the title Fix HashStringAllocator Fix HashStringAllocator::clear() and cumulativeBytes_ Jun 19, 2024
@wypb wypb force-pushed the fix_HashStringAllocator branch 3 times, most recently from 0e426e0 to 34b7f9e Compare June 20, 2024 04:03
@wypb
Copy link
Contributor Author

wypb commented Jun 24, 2024

Hi @xiaoxmeng can you please help review this? Thanks!

@mbasmanova mbasmanova requested a review from xiaoxmeng June 25, 2024 14:56
Copy link
Contributor

@xiaoxmeng xiaoxmeng left a comment

Choose a reason for hiding this comment

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

@wypb thanks!

@@ -305,7 +305,8 @@ class HashStringAllocator : public StreamArena {
/// the pointer because in the worst case we would have one allocation that
/// chains many small free blocks together via kContinued.
uint64_t freeSpace() const {
int64_t minFree = freeBytes_ - numFree_ * (sizeof(Header) + sizeof(void*));
int64_t minFree =
Copy link
Contributor

Choose a reason for hiding this comment

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

const int64_t minFree

@@ -433,8 +470,8 @@ void HashStringAllocator::free(Header* header) {
freeToPool(headerToFree, headerToFree->size() + sizeof(Header));
} else {
VELOX_CHECK(!headerToFree->isFree());
freeBytes_ += headerToFree->size() + sizeof(Header);
cumulativeBytes_ -= headerToFree->size();
freeBytes_ += headerToFree->size() + kHeaderSize;
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we add a anonymous function say

inline size_t blockBytes(blockHeader) {
  return blockHeader->size() + kHeaderSize;
}

@@ -697,15 +734,15 @@ int64_t HashStringAllocator::checkConsistency() const {
*(reinterpret_cast<int32_t*>(header->end()) - 1));
}
++numFree;
freeBytes += sizeof(Header) + header->size();
freeBytes += kHeaderSize + header->size();
Copy link
Contributor

Choose a reason for hiding this comment

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

ditto

} else if (header->isContinued()) {
// If the content of the header is continued, check the continued
// header is readable and not free.
auto* continued = header->nextContinued();
VELOX_CHECK(!continued->isFree());
allocatedBytes += header->size() - sizeof(void*);
allocatedBytes += header->size() + kHeaderSize;
Copy link
Contributor

Choose a reason for hiding this comment

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

ditto

velox/common/memory/HashStringAllocator.cpp Show resolved Hide resolved

static const auto kHugePageSize = memory::AllocationTraits::kHugePageSize;
for (auto i = 0; i < pool_.numRanges(); ++i) {
auto topRange = pool_.rangeAt(i);
Copy link
Contributor

Choose a reason for hiding this comment

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

const auto topRange = pool_.rangeAt(i);
const auto topRangeSize = topRange.size();

std::min<int64_t>(topRangeSize, kHugePageSize));
const auto size = range.size() - simd::kPadding;
auto* end = reinterpret_cast<Header*>(range.data() + size);
auto* header = reinterpret_cast<Header*>(range.data());
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we have define macro for this?

#define HEADER(ptr) reinterpret_cast<Header*>(ptr) 

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Because Velox does not recommend using macros, so I created a new static Header* castToHeader(const void* data) method.

velox/common/memory/HashStringAllocator.cpp Show resolved Hide resolved
@wypb wypb force-pushed the fix_HashStringAllocator branch 5 times, most recently from 587fd5d to 15ed556 Compare June 26, 2024 10:00
@wypb
Copy link
Contributor Author

wypb commented Jun 26, 2024

Hi @xiaoxmeng I have refactored the code based on the review comments. please help me review it again when you have a chance. Thanks!

Copy link
Contributor

@xiaoxmeng xiaoxmeng left a comment

Choose a reason for hiding this comment

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

@wypb LGTM. Thanks for helping on this!

velox/common/memory/HashStringAllocator.h Show resolved Hide resolved
@@ -83,6 +83,10 @@ std::string HashStringAllocator::Header::toString() {

HashStringAllocator::~HashStringAllocator() {
clear();
#ifdef NDEBUG
VELOX_CHECK_EQ(state_.cumulativeBytes(), 0);
Copy link
Contributor

Choose a reason for hiding this comment

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

You can use VELOX_DCHECK_EQ here?

Copy link
Contributor

Choose a reason for hiding this comment

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

Can you move these two checks in clear()?

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've moved it in clear() as suggested. Thanks.

#ifdef NDEBUG
static const auto kHugePageSize = memory::AllocationTraits::kHugePageSize;
for (auto i = 0; i < state_.pool().numRanges(); ++i) {
const auto topRange = state_.pool().rangeAt(i);
Copy link
Contributor

Choose a reason for hiding this comment

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

    const auto range = state_.pool().rangeAt(i);
    const auto rangeSize = topRange.size();

VELOX_CHECK_EQ(0, topRangeSize % kHugePageSize);
}

for (int64_t subRangeStart = 0; subRangeStart < topRangeSize;
Copy link
Contributor

Choose a reason for hiding this comment

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

s/subRangeStart/blockOffset/

reinterpret_cast<char*>(header->end()),
reinterpret_cast<char*>(end));

if (header->isFree()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

if (!header->isFree()) {
  ...
}

velox/common/memory/HashStringAllocator.cpp Show resolved Hide resolved

for (int64_t subRangeStart = 0; subRangeStart < topRangeSize;
subRangeStart += kHugePageSize) {
auto range = folly::Range<char*>(
Copy link
Contributor

Choose a reason for hiding this comment

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

s/range/blockRange/

velox/common/memory/HashStringAllocator.cpp Show resolved Hide resolved
@facebook-github-bot
Copy link
Contributor

@xiaoxmeng has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator.

@xiaoxmeng
Copy link
Contributor

Hi @xiaoxmeng I have refactored the code based on the review comments. please help me review it again when you have a chance. Thanks!

@wypb thanks and left few more nits. Thanks!

@wypb wypb force-pushed the fix_HashStringAllocator branch 2 times, most recently from 55ee1c2 to 13106b4 Compare June 27, 2024 06:47
@wypb wypb force-pushed the fix_HashStringAllocator branch from ab38741 to 6d2b30e Compare June 27, 2024 06:51
@facebook-github-bot
Copy link
Contributor

@xiaoxmeng has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator.

@facebook-github-bot
Copy link
Contributor

@xiaoxmeng merged this pull request in c54e59d.

Copy link

Conbench analyzed the 1 benchmark run on commit c54e59db.

There were no benchmark performance regressions. 🎉

The full Conbench report has more details.

@wypb wypb deleted the fix_HashStringAllocator branch June 29, 2024 05:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. Merged
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants