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

Eliminate memory allocation from critical path: #4353

Merged
merged 1 commit into from
Mar 16, 2023
Merged

Eliminate memory allocation from critical path: #4353

merged 1 commit into from
Mar 16, 2023

Conversation

nbougalis
Copy link
Contributor

When writing objects to the NodeStore, we need to convert them from the in-memory format to the binary format used by the node store.

The conversion is handled by the EncodedBlob class, which is only instantianted on the stack. Coupled with the fact that most objects are under 1024 bytes in size, this presents an opportunity to elide a memory allocation in a critical path.

This commit also makes the interface of EncodedBlob simpler while also eliminating a subtle corner case that could result in dangling pointers.

High Level Overview of Change

Context of Change

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Refactor (non-breaking change that only restructures code)
  • Tests (You added tests for code that already exists, or your new feature included in this PR)
  • Documentation Updates
  • Release

@intelliot
Copy link
Collaborator

(note: would like this to be tested on some full-history servers)

@intelliot
Copy link
Collaborator

(run on 2 full history servers in production; see if there is reduced memory usage)

@mtrippled
Copy link
Collaborator

(run on 2 full history servers in production; see if there is reduced memory usage)

@manojsdoshi (I don't know Xun's git handle). Elliot is asking for this branch to be run on 2 full history servers and to compare memory usage before and after, please.

@nbougalis
Copy link
Contributor Author

nbougalis commented Jan 4, 2023

(run on 2 full history servers in production; see if there is reduced memory usage)

I don't expect we'll see significant reduction in memory usage for this PR. It simply eschews the use of and std::shared_ptr when it's unnecessary and tries to avoid using the heap whenever possible, opting to use stack-based memory allocation instead.

While I'm confident that this is a net gain both in terms of memory usage (lower fragmentation) and perfromance (less work to do at runtime), the reality is that those gains are probably not directly measurable.

Not saying you shouldn't run this to test; definitely do that. But I don't think the merging criterion should be whether there's observable reduction in memory usage. Tagging @mtrippled, @HowardHinnant for their thoughts.

I do have an idea for something that could significantly reduce memory usage (to the tune of ~600MB) and (theoretically) improve performance. It's the same principle as the #4218, but for NodeObject instead: reduce the size of NodeObject by allocating the dynamic buffer immediately after the object itself, switch from std::shared_ptr to boost::intrusive_ptr and leverage SlabAllocator to grab memory more efficiently. If someone wants to tackle that, please feel free. The biggest challenge will be the TaggedCache we use to cache NodeObject instances; that code relies on std::shared_ptr and std::weak_ptr so some rethinking would be necessary.

@intelliot intelliot added Request for Comments Food for Thought Ideas, moonshots, etc. Stuff to think about broadly. Not necessarily directly actionable. Low Priority Needs Review labels Jan 4, 2023
@intelliot intelliot requested review from drlongle and removed request for cjcobb23 February 8, 2023 00:55
When writing objects to the NodeStore, we need to convert them from
the in-memory format to the binary format used by the node store.

The conversion is handled by the `EncodedBlob` class, which is only
instantianted on the stack. Coupled with the fact that most objects
are under 1024 bytes in size, this presents an opportunity to elide
a memory allocation in a critical path.

This commit also makes the interface of `EncodedBlob` simpler while
also eliminating a subtle corner case that could result in dangling
pointers.
Copy link
Collaborator

@mtrippled mtrippled left a comment

Choose a reason for hiding this comment

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

👍 LGTM

@intelliot intelliot assigned xzhaous and unassigned mtrippled Feb 23, 2023
@intelliot intelliot added this to the 1.10.1 milestone Feb 23, 2023
@intelliot
Copy link
Collaborator

intelliot commented Feb 23, 2023

@nbougalis if you feel this is ready to merge, please put the Passed label on it.

@nbougalis nbougalis added the Passed Passed code review & PR owner thinks it's ready to merge. Perf sign-off may still be required. label Mar 16, 2023
@intelliot intelliot merged commit 150d4a4 into XRPLF:develop Mar 16, 2023
@intelliot intelliot modified the milestones: Post-1.10.0, 1.11.0 Oct 11, 2023
@nbougalis nbougalis deleted the eb_alloc branch October 16, 2023 06:00
@intelliot intelliot added Perf Test Desired (Optional) RippleX Perf Team should look at this PR. The PR will not necessarily wait for testing to finish and removed Performance/Resource Improvement labels Jan 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Food for Thought Ideas, moonshots, etc. Stuff to think about broadly. Not necessarily directly actionable. Passed Passed code review & PR owner thinks it's ready to merge. Perf sign-off may still be required. Perf Test Desired (Optional) RippleX Perf Team should look at this PR. The PR will not necessarily wait for testing to finish Request for Comments
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

6 participants