ENH: use unique_ptr for memory management of profiling

- makes it easier to distinguish between pointers referring to pool
  data versus pointers actually holding storage, avoids
  manual demand-driven deletion and autoPtr.

ENH: simplify/improve Pstream profiling

- times now double (not scalar) for consistency with what cpuTime
  delivers

- use bool to track suspend state
This commit is contained in:
Mark Olesen 2020-07-09 14:04:06 +02:00
parent b64ada3dde
commit a088bda4d2
10 changed files with 179 additions and 218 deletions

View File

@ -31,10 +31,8 @@ License
#include "argList.H"
#include "HashSet.H"
#include "profiling.H"
#include "demandDrivenData.H"
#include "IOdictionary.H"
#include "registerSwitch.H"
#include <sstream>
// * * * * * * * * * * * * * Static Member Data * * * * * * * * * * * * * * //
@ -762,7 +760,7 @@ Foam::autoPtr<Foam::Time> Foam::Time::New(const argList& args)
Foam::Time::~Time()
{
deleteDemandDrivenData(loopProfiling_);
loopProfiling_.reset(nullptr);
forAllReverse(controlDict_.watchIndices(), i)
{
@ -889,7 +887,7 @@ Foam::Time::stopAtControls Foam::Time::stopAt() const
bool Foam::Time::run() const
{
deleteDemandDrivenData(loopProfiling_);
loopProfiling_.reset(nullptr);
bool isRunning = value() < (endTime_ - 0.5*deltaT_);
@ -948,8 +946,10 @@ bool Foam::Time::run() const
// (re)trigger profiling
if (profiling::active())
{
loopProfiling_ =
new profilingTrigger("time.run() " + objectRegistry::name());
loopProfiling_.reset
(
new profilingTrigger("time.run() " + objectRegistry::name())
);
}
}

View File

@ -133,7 +133,7 @@ private:
// Private data
//- Profiling trigger for time-loop (for run, loop)
mutable profilingTrigger* loopProfiling_;
mutable std::unique_ptr<profilingTrigger> loopProfiling_;
//- Any loaded dynamic libraries. Make sure to construct before
// reading controlDict.

View File

@ -32,17 +32,16 @@ License
#include "profilingSysInfo.H"
#include "cpuInfo.H"
#include "memInfo.H"
#include "demandDrivenData.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
int Foam::profiling::allowed(Foam::debug::infoSwitch("allowProfiling", 1));
Foam::profiling* Foam::profiling::singleton_(nullptr);
std::unique_ptr<Foam::profiling> Foam::profiling::singleton_(nullptr);
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
Foam::profilingInformation* Foam::profiling::create(const zero)
Foam::profilingInformation* Foam::profiling::create()
{
// Top-level entry: reset everything
pool_.clear();
@ -50,7 +49,7 @@ Foam::profilingInformation* Foam::profiling::create(const zero)
stack_.clear();
times_.clear();
Information* info = new Information();
Information* info = new Information;
pool_.append(info);
children_.resize(pool_.size());
@ -151,7 +150,7 @@ void Foam::profiling::initialize
{
if (allowed && !singleton_)
{
singleton_ = new profiling(ioObj, owner);
singleton_.reset(new profiling(ioObj, owner));
}
}
@ -165,7 +164,7 @@ void Foam::profiling::initialize
{
if (allowed && !singleton_)
{
singleton_ = new profiling(dict, ioObj, owner);
singleton_.reset(new profiling(dict, ioObj, owner));
}
}
@ -174,8 +173,7 @@ void Foam::profiling::stop(const Time& owner)
{
if (singleton_ && &owner == &(singleton_->owner_))
{
delete singleton_;
singleton_ = nullptr;
singleton_.reset(nullptr);
}
}
@ -214,8 +212,8 @@ void Foam::profiling::unstack(const profilingInformation *info)
if (info->id() != top->id())
{
FatalErrorInFunction
<< "The profiling information to unstack has different"
<< " id than on the top of the profiling stack" << nl
<< "Profiling information to unstack has different id than"
<< " the top of the profiling stack" << nl
<< " info: " << info->id() << " (" << info->description()
<< ")\n"
<< " top: " << top->id() << " (" << top->description()
@ -231,7 +229,8 @@ void Foam::profiling::unstack(const profilingInformation *info)
Foam::profiling::profiling
(
const IOobject& io,
const Time& owner
const Time& owner,
const bool allEnabled
)
:
IOdictionary(io),
@ -240,11 +239,18 @@ Foam::profiling::profiling
children_(),
stack_(),
times_(),
sysInfo_(new profilingSysInfo()),
cpuInfo_(new cpuInfo()),
memInfo_(new memInfo())
sysInfo_(nullptr),
cpuInfo_(nullptr),
memInfo_(nullptr)
{
Information *info = this->create(Zero);
if (allEnabled)
{
sysInfo_.reset(new profilingSysInfo);
cpuInfo_.reset(new cpuInfo);
memInfo_.reset(new memInfo);
}
Information *info = this->create();
this->beginTimer(info);
DetailInfo << "profiling initialized" << nl;
@ -258,32 +264,20 @@ Foam::profiling::profiling
const Time& owner
)
:
IOdictionary(io),
owner_(owner),
pool_(),
children_(),
stack_(),
times_(),
sysInfo_
(
dict.getOrDefault("sysInfo", false)
? new profilingSysInfo() : nullptr
),
cpuInfo_
(
dict.getOrDefault("cpuInfo", false)
? new cpuInfo() : nullptr
),
memInfo_
(
dict.getOrDefault("memInfo", false)
? new memInfo() : nullptr
)
profiling(io, owner, false)
{
Information *info = this->create(Zero);
this->beginTimer(info);
DetailInfo << "profiling initialized" << nl;
if (dict.getOrDefault("sysInfo", false))
{
sysInfo_.reset(new profilingSysInfo);
}
if (dict.getOrDefault("cpuInfo", false))
{
cpuInfo_.reset(new cpuInfo);
}
if (dict.getOrDefault("memInfo", false))
{
memInfo_.reset(new memInfo);
}
}
@ -291,13 +285,9 @@ Foam::profiling::profiling
Foam::profiling::~profiling()
{
deleteDemandDrivenData(sysInfo_);
deleteDemandDrivenData(cpuInfo_);
deleteDemandDrivenData(memInfo_);
if (singleton_ == this)
if (this == singleton_.get())
{
singleton_ = nullptr;
singleton_.reset(nullptr);
}
}

View File

@ -30,7 +30,7 @@ Class
Description
Code profiling.
This is typically activated from within the system/controlDict as follows
This is typically activated from within system/controlDict as follows
(defaults shown):
\code
profiling
@ -61,17 +61,20 @@ SourceFiles
#include "PtrDynList.H"
#include "Time.H"
#include "clockTime.H"
#include <memory>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declaration of classes
// Forward Declarations
class Ostream;
class cpuInfo;
class memInfo;
class profilingInformation;
class profilingSysInfo;
class profilingTrigger;
/*---------------------------------------------------------------------------*\
Class profiling Declaration
@ -88,14 +91,15 @@ public:
typedef profilingInformation Information;
typedef profilingTrigger Trigger;
// Static data members
// Static Data Members
//- Flag if profiling is allowed
static int allowed;
private:
// Private classes, typedefs
// Private Typedefs
typedef profilingSysInfo sysInfo;
@ -103,7 +107,7 @@ private:
// Private Static Data Members
//- Only one global object is possible
static profiling* singleton_;
static std::unique_ptr<profiling> singleton_;
// Private Data Members
@ -111,7 +115,7 @@ private:
//- The owner of the profiling
const Time& owner_;
//- Storage of profiling information
//- Storage of profiling information (memory management)
PtrDynList<Information> pool_;
//- Parent/child relationships for lookup purposes
@ -124,13 +128,13 @@ private:
DynamicList<clockValue> times_;
//- General system information (optional)
sysInfo* sysInfo_;
std::unique_ptr<sysInfo> sysInfo_;
//- CPU-Information (optional)
cpuInfo* cpuInfo_;
std::unique_ptr<cpuInfo> cpuInfo_;
//- MEM-Information (optional)
memInfo* memInfo_;
std::unique_ptr<memInfo> memInfo_;
// Private Member Functions
@ -153,7 +157,12 @@ protected:
// Constructors
//- Construct IO object, everything enabled
profiling(const IOobject& io, const Time& owner);
profiling
(
const IOobject& io,
const Time& owner,
const bool allEnabled = true
);
//- Construct IO object with finer control over behaviour
profiling
@ -164,15 +173,11 @@ protected:
);
//- Destructor
~profiling();
// Protected Member Functions
//- Clear all profiling and restart with new profiling
// \return pointer to stored information element
Information* create(const zero);
Information* create();
//- Get or create named profiling information element with the
//- specified parent.
@ -218,8 +223,13 @@ protected:
//- Remove the information from the top of the stack
static void unstack(const profilingInformation* info);
public:
//- Destructor. Top-level clears the singleton.
~profiling();
// Static Member Functions
//- True if profiling is allowed and is active

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2009-2016 Bernhard Gschaider
Copyright (C) 2016-2018 OpenCFD Ltd.
Copyright (C) 2016-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -27,8 +27,8 @@ License
\*---------------------------------------------------------------------------*/
#include "profilingInformation.H"
#include "Switch.H"
#include "IOstreams.H"
#include "Switch.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
@ -93,8 +93,6 @@ Foam::Ostream& Foam::profilingInformation::write
const scalar childTimes
) const
{
// write in dictionary format
os.beginBlock(word("trigger" + Foam::name(id_)));
os.writeEntry("id", id_);
@ -104,7 +102,7 @@ Foam::Ostream& Foam::profilingInformation::write
os.writeEntry("totalTime", totalTime() + elapsedTime);
os.writeEntry("childTime", childTime() + childTimes);
os.writeEntryIfDifferent<int>("maxMem", 0, maxMem_);
os.writeEntry("active", Switch(active()));
os.writeEntry("active", Switch::name(active()));
os.endBlock();
@ -112,7 +110,7 @@ Foam::Ostream& Foam::profilingInformation::write
}
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
Foam::Ostream& Foam::operator<<(Ostream& os, const profilingInformation& info)
{

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2009-2016 Bernhard Gschaider
Copyright (C) 2016-2017 OpenCFD Ltd.
Copyright (C) 2016-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -47,12 +47,8 @@ SourceFiles
namespace Foam
{
// Forward declarations
class profilingInformation;
class Ostream;
Ostream& operator<<(Ostream& os, const profilingInformation& info);
// Forward Declarations
class profiling;
/*---------------------------------------------------------------------------*\
Class profilingInformation Declaration
@ -60,7 +56,7 @@ Ostream& operator<<(Ostream& os, const profilingInformation& info);
class profilingInformation
{
// Private Data Members
// Private Data
//- Unique id to identify it
const label id_;
@ -88,7 +84,24 @@ class profilingInformation
mutable bool active_;
// Private Member Functions
protected:
// Friendship
//- Allow creation of master-element, setActive etc.
friend class profiling;
// Constructors
//- Default construct - only the master-element
profilingInformation();
// Protected Member Functions
//- Mark as being active or passive)
void setActive(bool state) const;
//- No copy construct
profilingInformation(const profilingInformation&) = delete;
@ -96,36 +109,6 @@ class profilingInformation
//- No copy assignment
void operator=(const profilingInformation&) = delete;
protected:
// Friendship
friend class profiling;
// Constructors
//- Construct null - only the master-element
profilingInformation();
// Member Functions
//- Mark as being active or passive)
void setActive(bool state) const;
//- Write the profiling times, optionally with additional values
// Use dictionary format.
Ostream& write
(
Ostream& os,
const bool offset = false,
const scalar elapsedTime = 0,
const scalar childTime = 0
) const;
public:
// Constructors
@ -147,49 +130,42 @@ public:
// Access
inline label id() const
label id() const
{
return id_;
}
inline const string& description() const
const string& description() const
{
return description_;
}
inline profilingInformation& parent() const
profilingInformation& parent() const
{
return *parent_;
}
inline label calls() const
label calls() const
{
return calls_;
}
inline scalar totalTime() const
scalar totalTime() const
{
return totalTime_;
}
inline scalar childTime() const
scalar childTime() const
{
return childTime_;
}
inline int maxMem() const
int maxMem() const
{
return maxMem_;
}
inline bool active() const
bool active() const
{
return active_;
}
@ -201,23 +177,32 @@ public:
void update(const scalar elapsedTime);
// IOstream Operators
// Write
friend Ostream& operator<<
//- Write the profiling times, optionally with additional values
// Uses dictionary format.
Ostream& write
(
Ostream& os,
const profilingInformation& info
);
const bool offset = false,
const scalar elapsedTime = 0,
const scalar childTime = 0
) const;
};
// Global Operators
Ostream& operator<<(Ostream& os, const profilingInformation& info);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2019 OpenCFD Ltd.
Copyright (C) 2019-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -29,11 +29,11 @@ License
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
Foam::autoPtr<Foam::cpuTime> Foam::profilingPstream::timer_(nullptr);
std::unique_ptr<Foam::cpuTime> Foam::profilingPstream::timer_(nullptr);
Foam::autoPtr<Foam::cpuTime> Foam::profilingPstream::suspend_(nullptr);
Foam::profilingPstream::timingList Foam::profilingPstream::times_(Zero);
Foam::FixedList<Foam::scalar, 5> Foam::profilingPstream::times_(Zero);
bool Foam::profilingPstream::suspend_(false);
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
@ -56,14 +56,9 @@ Foam::profilingPstream::~profilingPstream()
void Foam::profilingPstream::enable()
{
if (timer_.valid())
if (timer_)
{
timer_->resetCpuTime(); // Not really needed ...
}
else if (suspend_.valid())
{
suspend_.swap(timer_);
timer_->resetCpuTime(); // Not really needed ...
timer_->resetCpuTime(); // Not necessarily required ...
}
else
{
@ -71,31 +66,14 @@ void Foam::profilingPstream::enable()
times_ = Zero;
}
suspend_.clear();
suspend_ = false;
}
void Foam::profilingPstream::disable()
{
timer_.clear();
suspend_.clear();
}
void Foam::profilingPstream::suspend()
{
suspend_.clear();
suspend_.swap(timer_);
}
void Foam::profilingPstream::resume()
{
if (suspend_.valid())
{
timer_.clear();
timer_.swap(suspend_);
}
timer_.reset(nullptr);
suspend_ = false;
}

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2019 OpenCFD Ltd.
Copyright (C) 2019-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -27,8 +27,8 @@ Class
Foam::profilingPstream
Description
Timers and values for simple (simplistic) mpi-profiling. The entire
class behaves as a singleton.
Timers and values for simple (simplistic) mpi-profiling.
The entire class behaves as a singleton.
SourceFiles
profilingPstream.C
@ -38,10 +38,9 @@ SourceFiles
#ifndef profilingPstream_H
#define profilingPstream_H
#include "autoPtr.H"
#include "cpuTime.H"
#include "scalar.H"
#include "FixedList.H"
#include <memory>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -54,37 +53,47 @@ namespace Foam
class profilingPstream
{
//- Timer to use
static autoPtr<cpuTime> timer_;
//- Stash for timer during suspend
static autoPtr<cpuTime> suspend_;
//- The timing values
static FixedList<scalar, 5> times_;
public:
//- Enumeration within times array
enum timingType
{
GATHER = 0,
SCATTER,
REDUCE,
WAIT,
ALL_TO_ALL
};
// Public Types
//- Enumeration within times array
enum timingType
{
GATHER = 0,
SCATTER,
REDUCE,
WAIT,
ALL_TO_ALL
};
//- The timing values
typedef FixedList<double, 5> timingList;
private:
// Private Static Data
//- The timer to use
static std::unique_ptr<cpuTime> timer_;
//- The timing values
static timingList times_;
//- Is timer in a suspend state?
static bool suspend_;
public:
// Constructors
//- Construct and enable global timer
//- Default construct, enables global timer
profilingPstream();
//- Destructor - remove global timer
//- Destructor, disables global timer
~profilingPstream();
@ -97,25 +106,31 @@ public:
static void disable();
//- Suspend use of timer (if active)
static void suspend();
inline static void suspend()
{
suspend_ = bool(timer_);
}
//- Resume use of timer (if previously active)
static void resume();
static void resume()
{
suspend_ = false;
}
//- Timer is active
inline static bool active()
{
return timer_.valid();
return !suspend_ && bool(timer_);
}
//- Access to the timing information
inline static FixedList<scalar, 5>& times()
inline static timingList& times()
{
return times_;
}
//- Access to the timing information
inline static scalar times(const enum timingType idx)
//- Access to the timing information at given index
inline static double times(const enum timingType idx)
{
return times_[idx];
}
@ -123,7 +138,7 @@ public:
//- Update timer prior to measurement
inline static void beginTiming()
{
if (timer_.valid())
if (active())
{
(void) timer_->cpuTimeIncrement();
}
@ -132,7 +147,7 @@ public:
//- Add time increment
inline static void addTime(const enum timingType idx)
{
if (timer_.valid())
if (active())
{
times_[idx] += timer_->cpuTimeIncrement();
}

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2016-2017 OpenCFD Ltd.
Copyright (C) 2016-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -42,9 +42,8 @@ SourceFiles
namespace Foam
{
// Forward declaration of classes
// Forward Declarations
class Ostream;
class profilingSysInfo;
/*---------------------------------------------------------------------------*\
Class profilingSysInfo Declaration
@ -54,21 +53,8 @@ class profilingSysInfo
{
public:
// Constructors
//- Construct null
profilingSysInfo() = default;
//- Destructor
~profilingSysInfo() = default;
// Member Functions
//- Update it with a new timing information
void update();
//- Write the profiling system-info, use dictionary format.
Ostream& write(Ostream& os) const;
};

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2009-2016 Bernhard Gschaider
Copyright (C) 2016-2018 OpenCFD Ltd.
Copyright (C) 2016-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -45,7 +45,7 @@ SourceFiles
namespace Foam
{
// Forward declarations
// Forward Declarations
class profilingInformation;
/*---------------------------------------------------------------------------*\
@ -73,7 +73,7 @@ public:
// Constructors
//- Construct null, no profiling trigger
//- Default construct, no profiling trigger
profilingTrigger();
//- Construct profiling with given description.
@ -98,7 +98,6 @@ public:
//- Stop triggered profiling
void stop();
};