-
Notifications
You must be signed in to change notification settings - Fork 6k
[Impeller] moved to one staging buffer pool #44172
Conversation
|
It looks like this pull request may not have tests. Please make sure to add tests before merging. If you need an exemption to this rule, contact Hixie on the #hackers channel in Chat (don't just cc him here, he won't see it! He's on Discord!). If you are not sure if you need tests, consider this rule of thumb: the purpose of a test is to make sure someone doesn't accidentally revert the fix. Ask yourself, is there anything in your PR that you feel it is important we not accidentally revert back to how it was before your fix? Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing. |
jonahwilliams
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You need to remove the Linear allocted bit from the pool or else there is a chance to just endlessly leak memory (as allocation only happens at the end).
Done. If we wanted to have a more optimal pool we could look into a ring buffer. Since in practice i'm seeing about 1/32 of the pool being used it's probably not hard for the algorithm to find space for new allocations. |
|
ring buffer isn't something we can use for this, only VMA or Vulkan supported allocation strategies are reasonable. |
jonahwilliams
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
The VMA documentation makes mention of using a ring buffer: https://gpuopen-librariesandsdks.github.io/VulkanMemoryAllocator/html/custom_memory_pools.html#linear_algorithm I've read through it a few times and I'm guessing you have to implement it yourself on top of the pool? It isn't very clear. |
|
That would be a ring buffer of VMA pools, each with a linear allocated bit set. That is the current implementation, which you are removing 😄 |
It's not that because it says the requirement is that the |
|
Ahh you got me! I think that might work except, what happens if we run out of memory? |
We wouldn't in the ring buffer case because we are limited by the swapchain images we have. At worst case we would have swapchain_number of resources in memory. When the last frame is rendered all of that space will be given back to the ring. When writing overlaps reading in a ring buffer its a buffer overrun and since in practice it looks like we are using at most 1.2 MB, lets say thats per frame, we'd never get close to that point with a 32MB ring. |
|
There is no bound on the amount of memory we can use per frame. A developer could create a picture with thousands of paths that leads to many MB of geometry. Anything is possible. |
|
auto label is removed for flutter/engine, pr: 44172, due to - The status or check suite Mac mac_clang_tidy has failed. Please fix the issues identified (or deflake) before re-applying this label. |
…131687) flutter/engine@ae535c0...e3f817c 2023-08-01 [email protected] [Impeller] moved to one staging buffer pool (flutter/engine#44172) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-engine-flutter-autoroll Please CC [email protected],[email protected],[email protected] on the revert to ensure that a human is aware of the problem. To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://bugs.chromium.org/p/skia/issues/entry?template=Autoroller+Bug Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
…lutter#131687) flutter/engine@ae535c0...e3f817c 2023-08-01 [email protected] [Impeller] moved to one staging buffer pool (flutter/engine#44172) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-engine-flutter-autoroll Please CC [email protected],[email protected],[email protected] on the revert to ensure that a human is aware of the problem. To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://bugs.chromium.org/p/skia/issues/entry?template=Autoroller+Bug Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
I measured the pool usage while using the wonderous app after having
consolidated the pools by printing capturing the pool usage after every
call of `vmaCreateBuffer`. The max number of allocations ever seen in
this pool were 1288704 B. Each of these pools are 32 MB. So this change
removes 64MB from the baseline memory usage of a Vulkan Flutter engine.
Worse case for a swapchain of 3 would be roughly 3 * 1.2 MB which is
well within the limits of the 32 MB buffer.
Using one pool also increases the likelihood that a buffer will have
been more recently used which leads to better memory performance.
This is safe to do since buffers will only be placed back into the pool
after they are disposed of.
## patch used for measuring
```diff
--- a/impeller/renderer/backend/vulkan/allocator_vk.cc
+++ b/impeller/renderer/backend/vulkan/allocator_vk.cc
@@ -474,6 +474,15 @@ std::shared_ptr<DeviceBuffer> AllocatorVK::OnCreateBuffer(
&buffer_allocation_info //
)};
+ VmaStatistics pool_stats;
+ ::vmaGetPoolStatistics(allocator_.get(), staging_buffer_pool_.get().pool,
+ &pool_stats);
+ static uint64_t s_max = 0;
+ if (pool_stats.allocationBytes > s_max) {
+ s_max = pool_stats.allocationBytes;
+ FML_LOG(ERROR) << "pool max: " << s_max;
+ }
+
if (result != vk::Result::eSuccess) {
VALIDATION_LOG << "Unable to allocate a device buffer: "
<< vk::to_string(result);
```
## Pre-launch Checklist
- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide] and the [C++,
Objective-C, Java style guides].
- [ ] I listed at least one issue that this PR fixes in the description
above.
- [ ] I added new tests to check the change I am making or feature I am
adding, or Hixie said the PR is test-exempt. See [testing the engine]
for instructions on writing and running engine tests.
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] I signed the [CLA].
- [x] All existing and new tests are passing.
If you need help, consider asking for advice on the #hackers-new channel
on [Discord].
<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/wiki/Tree-hygiene#overview
[Tree Hygiene]: https://github.com/flutter/flutter/wiki/Tree-hygiene
[Flutter Style Guide]:
https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo
[C++, Objective-C, Java style guides]:
https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
[testing the engine]:
https://github.com/flutter/flutter/wiki/Testing-the-engine
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/wiki/Tree-hygiene#handling-breaking-changes
[Discord]: https://github.com/flutter/flutter/wiki/Chat
I measured the pool usage while using the wonderous app after having consolidated the pools by printing capturing the pool usage after every call of
vmaCreateBuffer. The max number of allocations ever seen in this pool were 1288704 B. Each of these pools are 32 MB. So this change removes 64MB from the baseline memory usage of a Vulkan Flutter engine. Worse case for a swapchain of 3 would be roughly 3 * 1.2 MB which is well within the limits of the 32 MB buffer.Using one pool also increases the likelihood that a buffer will have been more recently used which leads to better memory performance.
This is safe to do since buffers will only be placed back into the pool after they are disposed of.
patch used for measuring
Pre-launch Checklist
///).If you need help, consider asking for advice on the #hackers-new channel on Discord.