Accurate measuring of memory usage under Linux.
* Change: In Hurricane::Timer, measuring memory usage through the increase of sbrk() gives erroneous results. Under Linux, now read the /proc/[pid]/statm which gives the real size of the virtual memory of the process. There is also code for reading /proc/[pid]/mmap but it gives only the resident size of the process (i.e. swapped pages are *not* accounteds). * Change: In Katabatic, Anabatic, Kite & Katana now reports the total memory size of the program.
This commit is contained in:
parent
086e40ec7d
commit
44a2f574bc
|
@ -977,8 +977,12 @@ namespace Anabatic {
|
||||||
result.str("");
|
result.str("");
|
||||||
result << _timer.getCombTime()
|
result << _timer.getCombTime()
|
||||||
<< "s, +" << (_timer.getIncrease()>>10) << "Kb/"
|
<< "s, +" << (_timer.getIncrease()>>10) << "Kb/"
|
||||||
<< (_timer.getMemorySize()>>10) << "Kb";
|
<< Timer::getStringMemory(Timer::getMemorySize());
|
||||||
cmess2 << Dots::asString( " - Raw measurements", result.str() ) << endl;
|
cmess2 << Dots::asString( " - Raw measurements", result.str() ) << endl;
|
||||||
|
|
||||||
|
// result.str("");
|
||||||
|
// result << Timer::getStringMemory(Timer::getMemorySize());
|
||||||
|
// cmess1 << Dots::asString( " - Total memory", result.str() ) << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -32,13 +32,16 @@
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
#include "hurricane/Timer.h"
|
#include <fstream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <iomanip>
|
||||||
|
#include "hurricane/Timer.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Hurricane {
|
namespace Hurricane {
|
||||||
|
|
||||||
|
|
||||||
size_t Timer::_baseMemorySize = (size_t)sbrk(0);
|
size_t Timer::_baseMemorySize = Timer::getMemorySize();
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
|
@ -47,7 +50,7 @@ namespace Hurricane {
|
||||||
|
|
||||||
Timer::Timer ( double limitInSec )
|
Timer::Timer ( double limitInSec )
|
||||||
: timeLimit(limitInSec)
|
: timeLimit(limitInSec)
|
||||||
, _memorySize((size_t)sbrk(0))
|
, _memorySize(getMemorySize())
|
||||||
{
|
{
|
||||||
status = TimerOff;
|
status = TimerOff;
|
||||||
}
|
}
|
||||||
|
@ -142,6 +145,75 @@ namespace Hurricane {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t Timer::getMemorySize ()
|
||||||
|
{
|
||||||
|
size_t s, m;
|
||||||
|
return getMemorySize(s,m);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t Timer::getMemorySize ( size_t& memory, size_t& shared )
|
||||||
|
{
|
||||||
|
#if !defined __linux__
|
||||||
|
return (size_t)sbrk( 0 );
|
||||||
|
#else
|
||||||
|
#if 0
|
||||||
|
string mmapFile = "/proc/" + to_string(getpid()) + "/maps" ;
|
||||||
|
ifstream mmap ( mmapFile );
|
||||||
|
char line [ 4096 ];
|
||||||
|
unsigned long long rmemory = 0;
|
||||||
|
unsigned long long rshared = 0;
|
||||||
|
|
||||||
|
while ( not mmap.eof() ) {
|
||||||
|
mmap.getline( line, 4096 );
|
||||||
|
const string sline ( line );
|
||||||
|
istringstream iss ( sline );
|
||||||
|
unsigned long long baddress = 0;
|
||||||
|
unsigned long long eaddress = 0;
|
||||||
|
string perms;
|
||||||
|
unsigned long long offset;
|
||||||
|
int major;
|
||||||
|
int minor;
|
||||||
|
unsigned long long inode;
|
||||||
|
string pathname;
|
||||||
|
char separ;
|
||||||
|
|
||||||
|
iss >> hex >> baddress >> separ >> eaddress >> dec >> perms >> offset
|
||||||
|
>> major >> separ >> minor >> inode >> pathname;
|
||||||
|
|
||||||
|
if (not pathname.empty() and pathname.compare(0,6,"[heap]") != 0)
|
||||||
|
rshared += eaddress - baddress;
|
||||||
|
else
|
||||||
|
rmemory += eaddress - baddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
memory = (size_t)rmemory;
|
||||||
|
shared = (size_t)rshared;
|
||||||
|
|
||||||
|
mmap.close();
|
||||||
|
return memory;
|
||||||
|
#endif
|
||||||
|
long pagesize = sysconf( _SC_PAGESIZE );
|
||||||
|
string statmFile = "/proc/" + to_string(getpid()) + "/statm" ;
|
||||||
|
ifstream statm ( statmFile );
|
||||||
|
unsigned long long size = 0;
|
||||||
|
unsigned long long resident = 0;
|
||||||
|
unsigned long long share = 0;
|
||||||
|
unsigned long long text = 0;
|
||||||
|
unsigned long long lib = 0;
|
||||||
|
unsigned long long data = 0;
|
||||||
|
unsigned long long dt = 0;
|
||||||
|
|
||||||
|
statm >> size >> resident >> share >> text >> lib >> data >> dt;
|
||||||
|
|
||||||
|
memory = (size_t)size * pagesize;
|
||||||
|
|
||||||
|
statm.close();
|
||||||
|
return memory;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
string Timer::_getString () const
|
string Timer::_getString () const
|
||||||
{
|
{
|
||||||
//CPUNormalizer cpunorm;
|
//CPUNormalizer cpunorm;
|
||||||
|
@ -196,15 +268,16 @@ namespace Hurricane {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
string Timer::getStringMemory ( size_t size ) {
|
string Timer::getStringMemory ( size_t size )
|
||||||
string s;
|
{
|
||||||
|
ostringstream oss;
|
||||||
|
|
||||||
if ( size >> 30 ) s = getString(size>>30) + "Mb";
|
if (size >> 30) oss << fixed << setprecision(1) << ((float)size)/powf(2.0,30.0) << "Gb";
|
||||||
else if ( size >> 20 ) s = getString(size>>20) + "Mb";
|
else if (size >> 20) oss << fixed << setprecision(1) << ((float)size)/powf(2.0,20.0) << "Mb";
|
||||||
else if ( size >> 10 ) s = getString(size>>10) + "Kb";
|
else if (size >> 10) oss << size << "Kb";
|
||||||
else s = getString(size) + " bytes";
|
else oss << size << " bytes";
|
||||||
|
|
||||||
return s;
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -34,8 +34,8 @@
|
||||||
//! author="Igor Markov 06/22/97 "
|
//! author="Igor Markov 06/22/97 "
|
||||||
// freely inspired from abktimer from UCLApack .... just no windows.
|
// freely inspired from abktimer from UCLApack .... just no windows.
|
||||||
|
|
||||||
#ifndef __HURRICANE_TIMER__
|
#ifndef HURRICANE_TIMER_H
|
||||||
#define __HURRICANE_TIMER__
|
#define HURRICANE_TIMER_H
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
@ -61,11 +61,12 @@ namespace Hurricane {
|
||||||
|
|
||||||
// Used to record the CPU time of process
|
// Used to record the CPU time of process
|
||||||
class Timer {
|
class Timer {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Static Methods.
|
// Static Methods.
|
||||||
static string getStringTime ( double duration );
|
static string getStringTime ( double duration );
|
||||||
static string getStringMemory ( size_t size );
|
static string getStringMemory ( size_t size );
|
||||||
|
static size_t getMemorySize ( size_t& memory, size_t& shared );
|
||||||
|
static size_t getMemorySize ();
|
||||||
// Constructors & Destructors.
|
// Constructors & Destructors.
|
||||||
Timer ( double limitInSec=0.0 );
|
Timer ( double limitInSec=0.0 );
|
||||||
~Timer () { };
|
~Timer () { };
|
||||||
|
@ -97,9 +98,8 @@ namespace Hurricane {
|
||||||
// (INT_MAX+0.0)/CLOCKS_PER_SEC) sec (can be 36 mins),
|
// (INT_MAX+0.0)/CLOCKS_PER_SEC) sec (can be 36 mins),
|
||||||
// call realTimeExpired() instead
|
// call realTimeExpired() instead
|
||||||
inline size_t getBaseMemorySize () const;
|
inline size_t getBaseMemorySize () const;
|
||||||
inline size_t getMemorySize () const;
|
size_t getIncrease () const;
|
||||||
inline size_t getIncrease () const;
|
void resetIncrease ();
|
||||||
inline void resetIncrease ();
|
|
||||||
string _getString () const;
|
string _getString () const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -111,18 +111,17 @@ namespace Hurricane {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Internal: Attributes.
|
// Internal: Attributes.
|
||||||
time_t realTime1;
|
time_t realTime1;
|
||||||
mutable time_t realTime2;
|
mutable time_t realTime2;
|
||||||
double UserTime1;
|
double UserTime1;
|
||||||
mutable double UserTime2;
|
mutable double UserTime2;
|
||||||
double SysTime1;
|
double SysTime1;
|
||||||
mutable double SysTime2;
|
mutable double SysTime2;
|
||||||
double timeLimit;
|
double timeLimit;
|
||||||
Status status;
|
Status status;
|
||||||
mutable struct rusage _ru;
|
mutable struct rusage _ru;
|
||||||
size_t _memorySize;
|
size_t _memorySize;
|
||||||
static size_t _baseMemorySize;
|
static size_t _baseMemorySize;
|
||||||
// Internal: Methods.
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -130,9 +129,8 @@ namespace Hurricane {
|
||||||
// Inline Functions.
|
// Inline Functions.
|
||||||
inline bool Timer::isStopped () const { return status == TimerOff; }
|
inline bool Timer::isStopped () const { return status == TimerOff; }
|
||||||
inline size_t Timer::getBaseMemorySize () const { return _baseMemorySize; }
|
inline size_t Timer::getBaseMemorySize () const { return _baseMemorySize; }
|
||||||
inline size_t Timer::getMemorySize () const { return _memorySize - _baseMemorySize; }
|
inline size_t Timer::getIncrease () const { return getMemorySize() - _memorySize; }
|
||||||
inline size_t Timer::getIncrease () const { return (size_t)(sbrk(0)) - _memorySize; }
|
inline void Timer::resetIncrease () { _memorySize = getMemorySize(); }
|
||||||
inline void Timer::resetIncrease () { _memorySize = (size_t)sbrk(0); }
|
|
||||||
|
|
||||||
|
|
||||||
inline double Timer::getRealTimeOnTheFly () const
|
inline double Timer::getRealTimeOnTheFly () const
|
||||||
|
@ -179,11 +177,10 @@ namespace Hurricane {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} // End of Hurricane namespace.
|
} // Hurricane namespace.
|
||||||
|
|
||||||
|
|
||||||
GETSTRING_VALUE_SUPPORT(Hurricane::Timer);
|
GETSTRING_VALUE_SUPPORT(Hurricane::Timer);
|
||||||
IOSTREAM_VALUE_SUPPORT(Hurricane::Timer);
|
IOSTREAM_VALUE_SUPPORT(Hurricane::Timer);
|
||||||
|
|
||||||
|
#endif // HURRICANE_TIMER_H
|
||||||
#endif // __HURRICANE_TIMER__
|
|
||||||
|
|
|
@ -383,7 +383,7 @@ namespace Katabatic {
|
||||||
result.str("");
|
result.str("");
|
||||||
result << _timer.getCombTime()
|
result << _timer.getCombTime()
|
||||||
<< "s, +" << (_timer.getIncrease()>>10) << "Kb/"
|
<< "s, +" << (_timer.getIncrease()>>10) << "Kb/"
|
||||||
<< (_timer.getMemorySize()>>10) << "Kb";
|
<< Timer::getStringMemory(Timer::getMemorySize());
|
||||||
cmess2 << Dots::asString( " - Raw measurements", result.str() ) << endl;
|
cmess2 << Dots::asString( " - Raw measurements", result.str() ) << endl;
|
||||||
|
|
||||||
if (not tag.empty()) {
|
if (not tag.empty()) {
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include "hurricane/Error.h"
|
#include "hurricane/Error.h"
|
||||||
#include "hurricane/Warning.h"
|
#include "hurricane/Warning.h"
|
||||||
#include "hurricane/Breakpoint.h"
|
#include "hurricane/Breakpoint.h"
|
||||||
|
#include "hurricane/Timer.h"
|
||||||
#include "hurricane/Layer.h"
|
#include "hurricane/Layer.h"
|
||||||
#include "hurricane/Net.h"
|
#include "hurricane/Net.h"
|
||||||
#include "hurricane/Pad.h"
|
#include "hurricane/Pad.h"
|
||||||
|
@ -128,6 +129,7 @@ namespace Katana {
|
||||||
using Hurricane::Error;
|
using Hurricane::Error;
|
||||||
using Hurricane::Warning;
|
using Hurricane::Warning;
|
||||||
using Hurricane::Breakpoint;
|
using Hurricane::Breakpoint;
|
||||||
|
using Hurricane::Timer;
|
||||||
using Hurricane::Box;
|
using Hurricane::Box;
|
||||||
using Hurricane::Torus;
|
using Hurricane::Torus;
|
||||||
using Hurricane::Layer;
|
using Hurricane::Layer;
|
||||||
|
@ -254,6 +256,9 @@ namespace Katana {
|
||||||
|
|
||||||
KatanaEngine* KatanaEngine::create ( Cell* cell )
|
KatanaEngine* KatanaEngine::create ( Cell* cell )
|
||||||
{
|
{
|
||||||
|
cmess1 << Dots::asString( " - Initial memory"
|
||||||
|
, Timer::getStringMemory(Timer::getMemorySize()) ) << endl;
|
||||||
|
|
||||||
KatanaEngine* katana = new KatanaEngine ( cell );
|
KatanaEngine* katana = new KatanaEngine ( cell );
|
||||||
|
|
||||||
katana->_postCreate();
|
katana->_postCreate();
|
||||||
|
|
|
@ -363,13 +363,19 @@ Vertex* KnikEngine::getVertex ( DbU::Unit x, DbU::Unit y )
|
||||||
void KnikEngine::printTime()
|
void KnikEngine::printTime()
|
||||||
// *************************
|
// *************************
|
||||||
{
|
{
|
||||||
|
ostringstream result;
|
||||||
|
|
||||||
cmess2 << " + Done in " << Timer::getStringTime(_timer.getCombTime())
|
cmess2 << " + Done in " << Timer::getStringTime(_timer.getCombTime())
|
||||||
<< " [+" << Timer::getStringMemory(_timer.getIncrease()) << "]." << endl;
|
<< " [+" << Timer::getStringMemory(_timer.getIncrease()) << "]." << endl;
|
||||||
cmess2 << " (raw measurements : " << _timer.getCombTime()
|
cmess2 << " (raw measurements : " << _timer.getCombTime()
|
||||||
<< "s [+" << (_timer.getIncrease()>>10) << "Ko/"
|
<< "s [+" << (_timer.getIncrease()>>10) << "Ko/"
|
||||||
<< (_timer.getMemorySize()>>10) << "Ko])" << endl;
|
<< (_timer.getMemorySize()>>10) << "Ko])" << endl;
|
||||||
|
|
||||||
|
result.str("");
|
||||||
|
result << _timer.getCombTime()
|
||||||
|
<< "s, +" << (_timer.getIncrease()>>10) << "Kb/"
|
||||||
|
<< Timer::getStringMemory(Timer::getMemorySize());
|
||||||
|
cmess2 << Dots::asString( " - Raw measurements", result.str() ) << endl;
|
||||||
}
|
}
|
||||||
// void KnikEngine::showEstimateOccupancy()
|
// void KnikEngine::showEstimateOccupancy()
|
||||||
// // *************************************
|
// // *************************************
|
||||||
|
@ -1070,6 +1076,12 @@ void KnikEngine::run( const map<Name,Net*>& excludedNets )
|
||||||
cmess1 << " o Global Routing Completed." << endl;
|
cmess1 << " o Global Routing Completed." << endl;
|
||||||
cmess1 << Dots::asString( " - Done in", result.str() ) << endl;
|
cmess1 << Dots::asString( " - Done in", result.str() ) << endl;
|
||||||
|
|
||||||
|
result.str("");
|
||||||
|
result << _timer.getCombTime()
|
||||||
|
<< "s, +" << (_timer.getIncrease()>>10) << "Kb/"
|
||||||
|
<< Timer::getStringMemory(Timer::getMemorySize());
|
||||||
|
cmess2 << Dots::asString( " - Raw measurements", result.str() ) << endl;
|
||||||
|
|
||||||
addMeasure<double> ( getCell(), "knikT", _timer.getCombTime () );
|
addMeasure<double> ( getCell(), "knikT", _timer.getCombTime () );
|
||||||
addMeasure<size_t> ( getCell(), "knikS", (_timer.getMemorySize() >> 20) );
|
addMeasure<size_t> ( getCell(), "knikS", (_timer.getMemorySize() >> 20) );
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue