mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: improvements in profiling (issue #648)
- include amount of free system memory in profiling, which can give an indication of when swapping is about to start - profilingSummary utility to collect profiling from parallel calculations. Collects profiling information from processor directories and summarize the time spent and number of calls as (max avg min) values.
This commit is contained in:
@ -36,83 +36,14 @@ Foam::memInfo::memInfo()
|
||||
:
|
||||
peak_(0),
|
||||
size_(0),
|
||||
rss_(0)
|
||||
rss_(0),
|
||||
free_(0)
|
||||
{
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::memInfo::~memInfo()
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
|
||||
//
|
||||
// Parse the following type of content.
|
||||
//
|
||||
// ===========================
|
||||
// VmPeak: 15920 kB
|
||||
// VmSize: 15916 kB
|
||||
// VmLck: 0 kB
|
||||
// VmPin: 0 kB
|
||||
// VmHWM: 6972 kB
|
||||
// VmRSS: 6972 kB
|
||||
// VmLib: 2208 kB
|
||||
// VmPTE: 52 kB
|
||||
// VmPMD: 12 kB
|
||||
// VmSwap: 0 kB
|
||||
|
||||
const Foam::memInfo& Foam::memInfo::update()
|
||||
{
|
||||
// Clear (invalidate) values first
|
||||
peak_ = size_ = rss_ = 0;
|
||||
std::string line;
|
||||
|
||||
unsigned nKeys = 0;
|
||||
|
||||
std::ifstream is("/proc/" + std::to_string(Foam::pid()) + "/status");
|
||||
while (is.good() && nKeys < 3) // Stop after getting the known keys
|
||||
{
|
||||
std::getline(is, line);
|
||||
|
||||
const auto keyLen = line.find(':');
|
||||
if (keyLen == std::string::npos)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Value is after the ':', but skip any leading whitespace since
|
||||
// strtoi will do it anyhow
|
||||
const auto begVal = line.find_first_not_of("\t :", keyLen);
|
||||
if (begVal == std::string::npos)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const std::string key = line.substr(0, keyLen);
|
||||
|
||||
if (key == "VmPeak")
|
||||
{
|
||||
peak_ = std::stoi(line.substr(begVal));
|
||||
++nKeys;
|
||||
}
|
||||
else if (key == "VmSize")
|
||||
{
|
||||
size_ = std::stoi(line.substr(begVal));
|
||||
++nKeys;
|
||||
}
|
||||
else if (key == "VmRSS")
|
||||
{
|
||||
rss_ = std::stoi(line.substr(begVal));
|
||||
++nKeys;
|
||||
}
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
bool Foam::memInfo::valid() const
|
||||
{
|
||||
@ -120,11 +51,116 @@ bool Foam::memInfo::valid() const
|
||||
}
|
||||
|
||||
|
||||
void Foam::memInfo::clear()
|
||||
{
|
||||
peak_ = size_ = rss_ = 0;
|
||||
free_ = 0;
|
||||
}
|
||||
|
||||
|
||||
const Foam::memInfo& Foam::memInfo::update()
|
||||
{
|
||||
clear();
|
||||
std::string line;
|
||||
|
||||
// "/proc/PID/status"
|
||||
// ===========================
|
||||
// VmPeak: 15920 kB
|
||||
// VmSize: 15916 kB
|
||||
// VmLck: 0 kB
|
||||
// VmPin: 0 kB
|
||||
// VmHWM: 6972 kB
|
||||
// VmRSS: 6972 kB
|
||||
// ...
|
||||
// Stop parsing when known keys have been extracted
|
||||
{
|
||||
std::ifstream is("/proc/" + std::to_string(Foam::pid()) + "/status");
|
||||
|
||||
for
|
||||
(
|
||||
unsigned nkeys = 3;
|
||||
nkeys && is.good() && std::getline(is, line);
|
||||
/*nil*/
|
||||
)
|
||||
{
|
||||
const auto delim = line.find(':');
|
||||
if (delim == std::string::npos)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const std::string key(line.substr(0, delim));
|
||||
|
||||
// std::stoi() skips whitespace before using as many digits as
|
||||
// possible. So just need to skip over the ':' and let stoi do
|
||||
// the rest
|
||||
|
||||
if (key == "VmPeak")
|
||||
{
|
||||
peak_ = std::stoi(line.substr(delim+1));
|
||||
--nkeys;
|
||||
}
|
||||
else if (key == "VmSize")
|
||||
{
|
||||
size_ = std::stoi(line.substr(delim+1));
|
||||
--nkeys;
|
||||
}
|
||||
else if (key == "VmRSS")
|
||||
{
|
||||
rss_ = std::stoi(line.substr(delim+1));
|
||||
--nkeys;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// "/proc/meminfo"
|
||||
// ===========================
|
||||
// MemTotal: 65879268 kB
|
||||
// MemFree: 51544256 kB
|
||||
// MemAvailable: 58999636 kB
|
||||
// Buffers: 2116 kB
|
||||
// ...
|
||||
// Stop parsing when known keys have been extracted
|
||||
{
|
||||
std::ifstream is("/proc/meminfo");
|
||||
|
||||
for
|
||||
(
|
||||
unsigned nkeys = 1;
|
||||
nkeys && is.good() && std::getline(is, line);
|
||||
/*nil*/
|
||||
)
|
||||
{
|
||||
const auto delim = line.find(':');
|
||||
if (delim == std::string::npos)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const std::string key = line.substr(0, delim);
|
||||
|
||||
// std::stoi() skips whitespace before using as many digits as
|
||||
// possible. So just need to skip over the ':' and let stoi do
|
||||
// the rest
|
||||
|
||||
if (key == "MemFree")
|
||||
{
|
||||
free_ = std::stoi(line.substr(delim+1));
|
||||
--nkeys;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
void Foam::memInfo::write(Ostream& os) const
|
||||
{
|
||||
os.writeEntry("size", size_);
|
||||
os.writeEntry("peak", peak_);
|
||||
os.writeEntry("rss", rss_);
|
||||
os.writeEntry("free", free_);
|
||||
}
|
||||
|
||||
|
||||
@ -133,7 +169,7 @@ void Foam::memInfo::write(Ostream& os) const
|
||||
Foam::Istream& Foam::operator>>(Istream& is, memInfo& m)
|
||||
{
|
||||
is.readBegin("memInfo");
|
||||
is >> m.peak_ >> m.size_ >> m.rss_;
|
||||
is >> m.peak_ >> m.size_ >> m.rss_ >> m.free_;
|
||||
is.readEnd("memInfo");
|
||||
|
||||
is.check(FUNCTION_NAME);
|
||||
@ -146,7 +182,8 @@ Foam::Ostream& Foam::operator<<(Ostream& os, const memInfo& m)
|
||||
os << token::BEGIN_LIST
|
||||
<< m.peak_ << token::SPACE
|
||||
<< m.size_ << token::SPACE
|
||||
<< m.rss_
|
||||
<< m.rss_ << token::SPACE
|
||||
<< m.free_
|
||||
<< token::END_LIST;
|
||||
|
||||
os.check(FUNCTION_NAME);
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
\\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd.
|
||||
\\/ M anipulation | Copyright (C) 2016-2017 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -25,10 +25,11 @@ Class
|
||||
Foam::memInfo
|
||||
|
||||
Description
|
||||
Memory usage information for the process running this object.
|
||||
Memory usage information for the current process, and the system memory
|
||||
that is free.
|
||||
|
||||
Note
|
||||
Uses the information from /proc/PID/status
|
||||
Uses the information from /proc/PID/status and from /proc/meminfo
|
||||
|
||||
SourceFiles
|
||||
memInfo.C
|
||||
@ -69,26 +70,33 @@ class memInfo
|
||||
//- Resident set size of the process (VmRSS in /proc/PID/status)
|
||||
int rss_;
|
||||
|
||||
//- System memory free (MemFree in /proc/meminfo)
|
||||
int free_;
|
||||
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct null
|
||||
//- Construct and populate with values
|
||||
memInfo();
|
||||
|
||||
|
||||
//- Destructor
|
||||
~memInfo();
|
||||
~memInfo() = default;
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Update according to /proc/PID/status contents
|
||||
//- True if the memory information appears valid
|
||||
bool valid() const;
|
||||
|
||||
//- Reset to zero
|
||||
void clear();
|
||||
|
||||
//- Update according to /proc/PID/status and /proc/memory contents
|
||||
const memInfo& update();
|
||||
|
||||
|
||||
// Access
|
||||
|
||||
//- Peak memory (VmPeak in /proc/PID/status) at last update()
|
||||
inline int peak() const
|
||||
{
|
||||
@ -107,8 +115,11 @@ public:
|
||||
return rss_;
|
||||
}
|
||||
|
||||
//- True if the memory information appears valid
|
||||
bool valid() const;
|
||||
//- System memory free (MemFree in /proc/meminfo)
|
||||
inline int free() const
|
||||
{
|
||||
return free_;
|
||||
}
|
||||
|
||||
|
||||
// Write
|
||||
|
||||
Reference in New Issue
Block a user