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)
|
if (len > 0)
|
||||||
{
|
{
|
||||||
// With sign-check to avoid spurious -Walloc-size-larger-than
|
// With sign-check to avoid spurious -Walloc-size-larger-than
|
||||||
T* nv = new T[len];
|
|
||||||
|
|
||||||
const label overlap = min(this->size_, 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
|
#ifdef USEMEMCPY
|
||||||
if (is_contiguous<T>::value)
|
if (is_contiguous<T>::value)
|
||||||
{
|
{
|
||||||
@ -69,12 +82,12 @@ void Foam::List<T>::doResize(const label len)
|
|||||||
nv[i] = std::move(vp[i]);
|
nv[i] = std::move(vp[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
clear();
|
delete[] this->v_;
|
||||||
this->size_ = len;
|
this->size_ = len;
|
||||||
this->v_ = nv;
|
this->v_ = nv;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Or only #ifdef FULLDEBUG
|
// Or only #ifdef FULLDEBUG
|
||||||
|
|||||||
Reference in New Issue
Block a user