Defer allocation in ContiguousContainerBase::Buffer |
||||||
Issue descriptionAs part of identifying redundant allocations in Chrome, I found that memory allocated by ContiguousContainerBase::Buffer::Buffer() sometimes is not really used, resulting in 98 KiB of zeroes (14 * 7200), see https://docs.google.com/spreadsheets/d/1HfHKXy4q-ytZ-nwPay8YYyVSn1o-X9I7cWzYlygvtwQ/edit#gid=167958829 Backtrace misses some calls (because of inlining), but here is what happens (Android, 32-bit): * DisplayItemList::Inputs::Inputs() creates ContiguousContainerBase object with the second argument of 7200 (LargestDisplayItemSize() * kDefaultNumDisplayItemsToReserve = 72 * 100) * ContiguousContainerBase::ContiguousContainerBase() calls AllocateNewBufferForNextAllocation() with 7200 * AllocateNewBufferForNextAllocation() creates ContiguousContainerBase::Buffer() with 7200 * ContiguousContainerBase::Buffer() allocates 7200 bytes * In some cases preallocated Buffer object is never written to (via Allocate()), and its data_ remains blob of zeroes I'm proposing deferring allocation of Buffer::data_ until it's really needed, i.e. until the first Buffer::Allocate() call. The change is simple: diff --git a/cc/base/contiguous_container.cc b/cc/base/contiguous_container.cc index d6280b4..6439ceb 100644 --- a/cc/base/contiguous_container.cc +++ b/cc/base/contiguous_container.cc @@ -17,7 +17,7 @@ static const unsigned kDefaultInitialBufferSize = 32; class ContiguousContainerBase::Buffer { public: explicit Buffer(size_t buffer_size) - : data_(new char[buffer_size]), end_(begin()), capacity_(buffer_size) {} + : end_(nullptr), capacity_(buffer_size) {} ~Buffer() {} @@ -28,6 +28,10 @@ class ContiguousContainerBase::Buffer { void* Allocate(size_t object_size) { DCHECK_GE(UnusedCapacity(), object_size); + if (!data_) { + data_.reset(new char[capacity_]); + end_ = begin(); + } void* result = end_; end_ += object_size; return result; @@ -40,8 +44,8 @@ class ContiguousContainerBase::Buffer { } private: - char* begin() { return &data_[0]; } - const char* begin() const { return &data_[0]; } + char* begin() { return data_.get(); } + const char* begin() const { return data_.get(); } // begin() <= end_ <= begin() + capacity_ std::unique_ptr<char[]> data_; (More info about the effort to kill redundant allocations is here: https://groups.google.com/a/chromium.org/forum/#!msg/project-trim/EiKXwnbTvbo/0z-Y5Kg1CgAJ)
,
Aug 18 2016
PTAL
,
Aug 18 2016
,
Aug 18 2016
,
Aug 18 2016
Seems okay to me along as iterating it before/after Allocate works correctly.
,
Aug 18 2016
You wanna send a patch for it? Can you ensure it's unit tested for the above?
,
Aug 18 2016
OK, I'll send a patch (and a test) a bit later.
,
Aug 18 2016
Equivalent changes to blink::ContiguousContainer, if applicable, would be appreciated.
,
Aug 24 2016
The following revision refers to this bug: https://chromium.googlesource.com/chromium/src.git/+/aa339ecad2407a5b3875dc597843b1634cec5445 commit aa339ecad2407a5b3875dc597843b1634cec5445 Author: dskiba <dskiba@google.com> Date: Wed Aug 24 23:53:03 2016 Defer allocation in cc::ContiguousContainerBase::Buffer. This CL optimizes memory usage of cc::ContiguousContainer by deferring memory allocation in ContiguousContainerBase::Buffer until the first Allocate() call. Previously memory was allocated in the Buffer constructor, and sometimes was never written to (see the bug for more info). BUG= 635142 CQ_INCLUDE_TRYBOTS=master.tryserver.blink:linux_precise_blink_rel Review-Url: https://codereview.chromium.org/2277433002 Cr-Commit-Position: refs/heads/master@{#414204} [modify] https://crrev.com/aa339ecad2407a5b3875dc597843b1634cec5445/cc/base/contiguous_container.cc [modify] https://crrev.com/aa339ecad2407a5b3875dc597843b1634cec5445/cc/base/contiguous_container_unittest.cc
,
Oct 2 2016
Is this fixed?
,
Oct 3 2016
Blink has similar class, and similar fix can be applied, but it my testing I never saw it having zero memory, and I don't have time now. So marking this as fixed. |
||||||
►
Sign in to add a comment |
||||||
Comment 1 by dskiba@chromium.org
, Aug 5 2016