mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: refine resizing of zero-sized DynamicList/DynamicField
- since List is being used to manage the storage content for
DynamicList, it needs to free old memory for zero-sized lists first.
Consider this case (slightly exaggerated):
line 0: DynamicList<label> list;
line 1: list.reserve(100000);
line 2: list.reserve(200000);
After line 0:
- list has size=0, capacity=0 and data=nullptr
After line 1:
- list has size=0, capacity=1e+5 and data != nullptr
After line 2:
- list has size=0, capacity=2e+5 and data != nullptr
---
The internal resizing associated with line 1 corresponds to what the
List resize would naturally do. Namely allocate new storage, copy/move
any overlapping elements (in this case none) before freeing the old
storage and replacing with new storage.
Applying the same resizing logic for line 2 means, however, that the
old memory (1e5) and new memory (2e5) are temporarily both
accessible - leading to an unnecessary memory peak.
Now: if there is no overlap, just remove old memory first.
This commit is contained in:
@ -46,12 +46,25 @@ void Foam::List<T>::doResize(const label len)
|
||||
if (len > 0)
|
||||
{
|
||||
// With sign-check to avoid spurious -Walloc-size-larger-than
|
||||
T* nv = new T[len];
|
||||
|
||||
const label overlap = min(this->size_, len);
|
||||
|
||||
if (overlap)
|
||||
if (!overlap)
|
||||
{
|
||||
// Can discard old content before allocating new storage.
|
||||
// - when used as storage for DynamicList, it is possible to have
|
||||
// a zero-sized List with a non-null data pointer.
|
||||
|
||||
if (this->v_) delete[] this->v_;
|
||||
this->size_ = len;
|
||||
this->v_ = new T[len];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Recover old (overlapping) content when resizing
|
||||
|
||||
T* nv = new T[len];
|
||||
|
||||
// ie, std::copy(this->v_, this->v_ + overlap, nv);
|
||||
#ifdef USEMEMCPY
|
||||
if (is_contiguous<T>::value)
|
||||
{
|
||||
@ -69,11 +82,11 @@ void Foam::List<T>::doResize(const label len)
|
||||
nv[i] = std::move(vp[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
clear();
|
||||
this->size_ = len;
|
||||
this->v_ = nv;
|
||||
delete[] this->v_;
|
||||
this->size_ = len;
|
||||
this->v_ = nv;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user