Add CPUMeter and ScopedTimeInterval

This commit is contained in:
Vinnie Falco
2013-10-04 10:56:19 -07:00
parent 3638485977
commit a23fb06409
7 changed files with 203 additions and 21 deletions

View File

@@ -84,8 +84,9 @@
<ClInclude Include="..\..\beast\Arithmetic.h" />
<ClInclude Include="..\..\beast\Atomic.h" />
<ClInclude Include="..\..\beast\ByteOrder.h" />
<ClInclude Include="..\..\beast\chrono\CPUUsage.h" />
<ClInclude Include="..\..\beast\chrono\CPUMeter.h" />
<ClInclude Include="..\..\beast\chrono\RelativeTime.h" />
<ClInclude Include="..\..\beast\chrono\ScopedTimeInterval.h" />
<ClInclude Include="..\..\beast\Config.h" />
<ClInclude Include="..\..\beast\config\CompilerConfig.h" />
<ClInclude Include="..\..\beast\config\compiler\Clang.h" />
@@ -398,7 +399,7 @@
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\beast\chrono\Chrono.cpp" />
<ClCompile Include="..\..\beast\chrono\impl\CPUUsage.cpp">
<ClCompile Include="..\..\beast\chrono\impl\CPUMeter.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>

View File

@@ -1224,9 +1224,6 @@
<ClInclude Include="..\..\modules\beast_asio\http\HTTPResponseParser.h">
<Filter>beast_asio\http</Filter>
</ClInclude>
<ClInclude Include="..\..\beast\chrono\CPUUsage.h">
<Filter>beast\chrono</Filter>
</ClInclude>
<ClInclude Include="..\..\beast\thread\RecursiveMutex.h">
<Filter>beast\thread</Filter>
</ClInclude>
@@ -1236,6 +1233,12 @@
<ClInclude Include="..\..\beast\thread\TryLockGuard.h">
<Filter>beast\thread</Filter>
</ClInclude>
<ClInclude Include="..\..\beast\chrono\ScopedTimeInterval.h">
<Filter>beast\chrono</Filter>
</ClInclude>
<ClInclude Include="..\..\beast\chrono\CPUMeter.h">
<Filter>beast\chrono</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\modules\beast_core\containers\AbstractFifo.cpp">
@@ -1775,15 +1778,15 @@
<ClCompile Include="..\..\modules\beast_asio\http\HTTPResponseParser.cpp">
<Filter>beast_asio\http</Filter>
</ClCompile>
<ClCompile Include="..\..\beast\chrono\impl\CPUUsage.cpp">
<Filter>beast\chrono\impl</Filter>
</ClCompile>
<ClCompile Include="..\..\beast\thread\impl\RecursiveMutex.cpp">
<Filter>beast\thread\impl</Filter>
</ClCompile>
<ClCompile Include="..\..\beast\thread\Thread.cpp">
<Filter>beast\thread</Filter>
</ClCompile>
<ClCompile Include="..\..\beast\chrono\impl\CPUMeter.cpp">
<Filter>beast\chrono\impl</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Text Include="..\..\TODO.txt">

View File

@@ -20,7 +20,8 @@
#ifndef BEAST_CHRONO_H_INCLUDED
#define BEAST_CHRONO_H_INCLUDED
#include "chrono/CPUUsage.h"
#include "chrono/CPUMeter.h"
#include "chrono/RelativeTime.h"
#include "chrono/ScopedTimeInterval.h"
#endif

View File

@@ -0,0 +1,159 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef BEAST_CHRONO_CPUMETER_H_INCLUDED
#define BEAST_CHRONO_CPUMETER_H_INCLUDED
#include "RelativeTime.h"
#include "SCopedTimeInterval.h"
#include "../thread/SharedData.h"
#include "../Atomic.h"
namespace beast {
/** Measurements of CPU utilization. */
class CPUMeter
{
private:
struct MeasureIdle
{
explicit MeasureIdle (CPUMeter& meter)
: m_meter (&meter)
{ }
void operator() (RelativeTime const& interval) const
{ m_meter->addIdleTime (interval); }
CPUMeter* m_meter;
};
struct MeasureActive
{
explicit MeasureActive (CPUMeter& meter)
: m_meter (&meter)
{ }
void operator() (RelativeTime const& interval) const
{ m_meter->addActiveTime (interval); }
CPUMeter* m_meter;
};
public:
/** The type of container that measures idle time. */
typedef ScopedTimeInterval <MeasureIdle> ScopedIdleTime;
typedef ScopedTimeInterval <MeasureActive> ScopedActiveTime;
/** Returns the fraction of time that the CPU is being used. */
double getCpuUsage () const
{
SharedState::ConstAccess state (m_state);
double const seconds (state->usage.seconds());
if (seconds > 0)
return (state->usage.active.inSeconds() / seconds);
return 0;
}
private:
enum
{
// The amount of time an aggregate must accrue before a swap
secondsPerAggregate = 3
// The number of aggregates in the rolling history buffer
,numberOfAggregates = 20
};
// Aggregated sample data
struct Aggregate
{
RelativeTime idle;
RelativeTime active;
// Returns the total number of seconds in the aggregate
double seconds () const
{ return idle.inSeconds() + active.inSeconds(); }
// Reset the accumulated times
void clear ()
{ idle = RelativeTime (0); active = RelativeTime (0); }
Aggregate& operator+= (Aggregate const& other)
{ idle += other.idle; active += other.active; return *this; }
Aggregate& operator-= (Aggregate const& other)
{ idle -= other.idle; active -= other.active; return *this; }
};
struct State
{
State () : index (0)
{
}
// Returns a reference to the current aggregate
Aggregate& front ()
{
return history [index];
}
// Checks the current aggregate to see if we should advance
void update()
{
if (front().seconds() >= secondsPerAggregate)
advance();
}
// Advance the index in the rolling history
void advance ()
{
usage += history [index];
index = (++index) % numberOfAggregates;
usage -= history [index];
history [index].clear ();
}
// Index of the current aggregate we are accumulating
int index;
// Delta summed usage over the entire history buffer
Aggregate usage;
// The rolling history buffer
Aggregate history [numberOfAggregates];
};
typedef SharedData <State> SharedState;
SharedState m_state;
void addIdleTime (RelativeTime const& interval)
{
SharedState::Access state (m_state);
state->front().idle += interval;
state->update();
}
void addActiveTime (RelativeTime const& interval)
{
SharedState::Access state (m_state);
state->front().active += interval;
state->update();
}
};
}
#endif

View File

@@ -19,5 +19,5 @@
#include "BeastConfig.h"
#include "impl/CPUUsage.cpp"
#include "impl/CPUMeter.cpp"
#include "impl/RelativeTime.cpp"

View File

@@ -17,27 +17,45 @@
*/
//==============================================================================
#ifndef BEAST_CHRONO_CPUUSAGE_H_INCLUDED
#define BEAST_CHRONO_CPUUSAGE_H_INCLUDED
#ifndef BEAST_CHRONO_SCOPEDTIMEINTERVAL_H_INCLUDED
#define BEAST_CHRONO_SCOPEDTIMEINTERVAL_H_INCLUDED
#include "../Uncopyable.h"
#include "RelativeTime.h"
namespace beast {
/** Measurements of CPU utilization. */
#if 0
/** Scoped lifetime measurement. */
class ScopedTimeInterval
/** Time measurement using scoped RAII container.
UnaryFunction will be called with this signature:
void (RelativeTime const& interval);
*/
template <class UnaryFunction>
class ScopedTimeInterval : public Uncopyable
{
public:
ScopedTimeInterval ();
~ScopedTimeInterval ();
/** Create the measurement with a default-constructed UnaryFunction. */
ScopedTimeInterval ()
: m_start (RelativeTime::fromStartup())
{
}
/** Create the measurement with UnaryFunction constructed from one argument. */
template <typename Arg>
explicit ScopedTimeInterval (Arg arg)
: m_func (arg)
, m_start (RelativeTime::fromStartup ())
{
}
~ScopedTimeInterval ()
{
m_func (RelativeTime::fromStartup() - m_start);
}
private:
UnaryFunction m_func;
RelativeTime m_start;
};
#endif
}

View File

@@ -17,5 +17,5 @@
*/
//==============================================================================
#include "../CPUUsage.h"
#include "../CPUMeter.h"