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 << _timer.getCombTime()
|
||||
<< "s, +" << (_timer.getIncrease()>>10) << "Kb/"
|
||||
<< (_timer.getMemorySize()>>10) << "Kb";
|
||||
<< Timer::getStringMemory(Timer::getMemorySize());
|
||||
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 {
|
||||
|
||||
|
||||
size_t Timer::_baseMemorySize = (size_t)sbrk(0);
|
||||
size_t Timer::_baseMemorySize = Timer::getMemorySize();
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
@ -47,7 +50,7 @@ namespace Hurricane {
|
|||
|
||||
Timer::Timer ( double limitInSec )
|
||||
: timeLimit(limitInSec)
|
||||
, _memorySize((size_t)sbrk(0))
|
||||
, _memorySize(getMemorySize())
|
||||
{
|
||||
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
|
||||
{
|
||||
//CPUNormalizer cpunorm;
|
||||
|
@ -196,15 +268,16 @@ namespace Hurricane {
|
|||
}
|
||||
|
||||
|
||||
string Timer::getStringMemory ( size_t size ) {
|
||||
string s;
|
||||
string Timer::getStringMemory ( size_t size )
|
||||
{
|
||||
ostringstream oss;
|
||||
|
||||
if ( size >> 30 ) s = getString(size>>30) + "Mb";
|
||||
else if ( size >> 20 ) s = getString(size>>20) + "Mb";
|
||||
else if ( size >> 10 ) s = getString(size>>10) + "Kb";
|
||||
else s = getString(size) + " bytes";
|
||||
if (size >> 30) oss << fixed << setprecision(1) << ((float)size)/powf(2.0,30.0) << "Gb";
|
||||
else if (size >> 20) oss << fixed << setprecision(1) << ((float)size)/powf(2.0,20.0) << "Mb";
|
||||
else if (size >> 10) oss << size << "Kb";
|
||||
else oss << size << " bytes";
|
||||
|
||||
return s;
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -34,8 +34,8 @@
|
|||
//! author="Igor Markov 06/22/97 "
|
||||
// freely inspired from abktimer from UCLApack .... just no windows.
|
||||
|
||||
#ifndef __HURRICANE_TIMER__
|
||||
#define __HURRICANE_TIMER__
|
||||
#ifndef HURRICANE_TIMER_H
|
||||
#define HURRICANE_TIMER_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
|
@ -61,11 +61,12 @@ namespace Hurricane {
|
|||
|
||||
// Used to record the CPU time of process
|
||||
class Timer {
|
||||
|
||||
public:
|
||||
// Static Methods.
|
||||
static string getStringTime ( double duration );
|
||||
static string getStringMemory ( size_t size );
|
||||
static size_t getMemorySize ( size_t& memory, size_t& shared );
|
||||
static size_t getMemorySize ();
|
||||
// Constructors & Destructors.
|
||||
Timer ( double limitInSec=0.0 );
|
||||
~Timer () { };
|
||||
|
@ -97,9 +98,8 @@ namespace Hurricane {
|
|||
// (INT_MAX+0.0)/CLOCKS_PER_SEC) sec (can be 36 mins),
|
||||
// call realTimeExpired() instead
|
||||
inline size_t getBaseMemorySize () const;
|
||||
inline size_t getMemorySize () const;
|
||||
inline size_t getIncrease () const;
|
||||
inline void resetIncrease ();
|
||||
size_t getIncrease () const;
|
||||
void resetIncrease ();
|
||||
string _getString () const;
|
||||
|
||||
protected:
|
||||
|
@ -111,18 +111,17 @@ namespace Hurricane {
|
|||
|
||||
private:
|
||||
// Internal: Attributes.
|
||||
time_t realTime1;
|
||||
mutable time_t realTime2;
|
||||
double UserTime1;
|
||||
mutable double UserTime2;
|
||||
double SysTime1;
|
||||
mutable double SysTime2;
|
||||
double timeLimit;
|
||||
Status status;
|
||||
mutable struct rusage _ru;
|
||||
size_t _memorySize;
|
||||
static size_t _baseMemorySize;
|
||||
// Internal: Methods.
|
||||
time_t realTime1;
|
||||
mutable time_t realTime2;
|
||||
double UserTime1;
|
||||
mutable double UserTime2;
|
||||
double SysTime1;
|
||||
mutable double SysTime2;
|
||||
double timeLimit;
|
||||
Status status;
|
||||
mutable struct rusage _ru;
|
||||
size_t _memorySize;
|
||||
static size_t _baseMemorySize;
|
||||
|
||||
};
|
||||
|
||||
|
@ -130,9 +129,8 @@ namespace Hurricane {
|
|||
// Inline Functions.
|
||||
inline bool Timer::isStopped () const { return status == TimerOff; }
|
||||
inline size_t Timer::getBaseMemorySize () const { return _baseMemorySize; }
|
||||
inline size_t Timer::getMemorySize () const { return _memorySize - _baseMemorySize; }
|
||||
inline size_t Timer::getIncrease () const { return (size_t)(sbrk(0)) - _memorySize; }
|
||||
inline void Timer::resetIncrease () { _memorySize = (size_t)sbrk(0); }
|
||||
inline size_t Timer::getIncrease () const { return getMemorySize() - _memorySize; }
|
||||
inline void Timer::resetIncrease () { _memorySize = getMemorySize(); }
|
||||
|
||||
|
||||
inline double Timer::getRealTimeOnTheFly () const
|
||||
|
@ -179,11 +177,10 @@ namespace Hurricane {
|
|||
}
|
||||
|
||||
|
||||
} // End of Hurricane namespace.
|
||||
} // Hurricane namespace.
|
||||
|
||||
|
||||
GETSTRING_VALUE_SUPPORT(Hurricane::Timer);
|
||||
IOSTREAM_VALUE_SUPPORT(Hurricane::Timer);
|
||||
|
||||
|
||||
#endif // __HURRICANE_TIMER__
|
||||
#endif // HURRICANE_TIMER_H
|
||||
|
|
|
@ -383,7 +383,7 @@ namespace Katabatic {
|
|||
result.str("");
|
||||
result << _timer.getCombTime()
|
||||
<< "s, +" << (_timer.getIncrease()>>10) << "Kb/"
|
||||
<< (_timer.getMemorySize()>>10) << "Kb";
|
||||
<< Timer::getStringMemory(Timer::getMemorySize());
|
||||
cmess2 << Dots::asString( " - Raw measurements", result.str() ) << endl;
|
||||
|
||||
if (not tag.empty()) {
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "hurricane/Error.h"
|
||||
#include "hurricane/Warning.h"
|
||||
#include "hurricane/Breakpoint.h"
|
||||
#include "hurricane/Timer.h"
|
||||
#include "hurricane/Layer.h"
|
||||
#include "hurricane/Net.h"
|
||||
#include "hurricane/Pad.h"
|
||||
|
@ -128,6 +129,7 @@ namespace Katana {
|
|||
using Hurricane::Error;
|
||||
using Hurricane::Warning;
|
||||
using Hurricane::Breakpoint;
|
||||
using Hurricane::Timer;
|
||||
using Hurricane::Box;
|
||||
using Hurricane::Torus;
|
||||
using Hurricane::Layer;
|
||||
|
@ -254,6 +256,9 @@ namespace Katana {
|
|||
|
||||
KatanaEngine* KatanaEngine::create ( Cell* cell )
|
||||
{
|
||||
cmess1 << Dots::asString( " - Initial memory"
|
||||
, Timer::getStringMemory(Timer::getMemorySize()) ) << endl;
|
||||
|
||||
KatanaEngine* katana = new KatanaEngine ( cell );
|
||||
|
||||
katana->_postCreate();
|
||||
|
|
|
@ -363,13 +363,19 @@ Vertex* KnikEngine::getVertex ( DbU::Unit x, DbU::Unit y )
|
|||
void KnikEngine::printTime()
|
||||
// *************************
|
||||
{
|
||||
ostringstream result;
|
||||
|
||||
cmess2 << " + Done in " << Timer::getStringTime(_timer.getCombTime())
|
||||
<< " [+" << Timer::getStringMemory(_timer.getIncrease()) << "]." << endl;
|
||||
cmess2 << " (raw measurements : " << _timer.getCombTime()
|
||||
<< "s [+" << (_timer.getIncrease()>>10) << "Ko/"
|
||||
<< (_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()
|
||||
// // *************************************
|
||||
|
@ -1070,6 +1076,12 @@ void KnikEngine::run( const map<Name,Net*>& excludedNets )
|
|||
cmess1 << " o Global Routing Completed." << 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<size_t> ( getCell(), "knikS", (_timer.getMemorySize() >> 20) );
|
||||
|
||||
|
|
Loading…
Reference in New Issue