Initial community commit
This commit is contained in:
parent
537bcbc862
commit
fc06254474
16440 changed files with 4239995 additions and 2 deletions
221
Src/external_dependencies/openmpt-trunk/common/Profiler.cpp
Normal file
221
Src/external_dependencies/openmpt-trunk/common/Profiler.cpp
Normal file
|
@ -0,0 +1,221 @@
|
|||
/*
|
||||
* Profiler.cpp
|
||||
* ------------
|
||||
* Purpose: Performance measuring
|
||||
* Notes : (currently none)
|
||||
* Authors: OpenMPT Devs
|
||||
* The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
|
||||
*/
|
||||
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "Profiler.h"
|
||||
|
||||
|
||||
OPENMPT_NAMESPACE_BEGIN
|
||||
|
||||
|
||||
#ifdef USE_PROFILER
|
||||
|
||||
|
||||
class Statistics
|
||||
{
|
||||
public:
|
||||
Profile &profile;
|
||||
Profile::Data data;
|
||||
double usage;
|
||||
Statistics(Profile &p) : profile(p)
|
||||
{
|
||||
usage = 0.0;
|
||||
Update();
|
||||
}
|
||||
void Update()
|
||||
{
|
||||
data = profile.GetAndResetData();
|
||||
uint64 now = profile.GetTime();
|
||||
uint64 timewindow = now - data.Start;
|
||||
if(data.Calls > 0 && timewindow > 0)
|
||||
{
|
||||
usage = (double)data.Sum / (double)timewindow;
|
||||
} else
|
||||
{
|
||||
usage = 0.0;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct ProfileBlock
|
||||
{
|
||||
class Profile * profile;
|
||||
const char * name;
|
||||
class Statistics * stats;
|
||||
};
|
||||
|
||||
static constexpr std::size_t MAX_PROFILES = 1024;
|
||||
|
||||
static ProfileBlock Profiles[ MAX_PROFILES ];
|
||||
|
||||
static std::size_t NextProfile = 0;
|
||||
|
||||
|
||||
static void RegisterProfile(Profile *newprofile)
|
||||
{
|
||||
if(NextProfile < MAX_PROFILES)
|
||||
{
|
||||
Profiles[NextProfile].profile = newprofile;
|
||||
Profiles[NextProfile].stats = 0;
|
||||
NextProfile++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void UnregisterProfile(Profile *oldprofile)
|
||||
{
|
||||
for(std::size_t i=0; i<NextProfile; i++) {
|
||||
if(Profiles[i].profile == oldprofile) {
|
||||
Profiles[i].profile = 0;
|
||||
delete Profiles[i].stats;
|
||||
Profiles[i].stats = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Profiler::Update()
|
||||
{
|
||||
for(std::size_t i=0; i<NextProfile; i++)
|
||||
{
|
||||
if(!Profiles[i].stats)
|
||||
{
|
||||
Profiles[i].stats = new Statistics(*Profiles[i].profile);
|
||||
} else
|
||||
{
|
||||
Profiles[i].stats->Update();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::string Profiler::DumpProfiles()
|
||||
{
|
||||
std::string ret;
|
||||
for(std::size_t i=0; i<NextProfile; i++)
|
||||
{
|
||||
if(Profiles[i].stats)
|
||||
{
|
||||
Statistics &stats = *Profiles[i].stats;
|
||||
std::string cat;
|
||||
switch(stats.profile.Category)
|
||||
{
|
||||
case Profiler::GUI: cat = "GUI"; break;
|
||||
case Profiler::Audio: cat = "Audio"; break;
|
||||
case Profiler::Notify: cat = "Notify"; break;
|
||||
}
|
||||
ret += cat + " " + std::string(stats.profile.Name) + ": " + mpt::afmt::right(6, mpt::afmt::fix(stats.usage * 100.0, 3)) + "%\r\n";
|
||||
}
|
||||
}
|
||||
ret += "\r\n";
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
std::vector<double> Profiler::DumpCategories()
|
||||
{
|
||||
std::vector<double> ret;
|
||||
ret.resize(Profiler::CategoriesCount);
|
||||
for(std::size_t i=0; i<NextProfile; i++)
|
||||
{
|
||||
if(Profiles[i].stats)
|
||||
{
|
||||
ret[Profiles[i].profile->Category] += Profiles[i].stats->usage;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
uint64 Profile::GetTime() const
|
||||
{
|
||||
LARGE_INTEGER ret;
|
||||
ret.QuadPart = 0;
|
||||
QueryPerformanceCounter(&ret);
|
||||
return ret.QuadPart;
|
||||
}
|
||||
|
||||
|
||||
uint64 Profile::GetFrequency() const
|
||||
{
|
||||
LARGE_INTEGER ret;
|
||||
ret.QuadPart = 0;
|
||||
QueryPerformanceFrequency(&ret);
|
||||
return ret.QuadPart;
|
||||
}
|
||||
|
||||
|
||||
Profile::Profile(Profiler::Category category, const char *name) : Category(category), Name(name)
|
||||
{
|
||||
data.Calls = 0;
|
||||
data.Sum = 0;
|
||||
data.Overhead = 0;
|
||||
data.Start = GetTime();
|
||||
EnterTime = 0;
|
||||
RegisterProfile(this);
|
||||
}
|
||||
|
||||
|
||||
Profile::~Profile()
|
||||
{
|
||||
UnregisterProfile(this);
|
||||
}
|
||||
|
||||
|
||||
Profile::Data Profile::GetAndResetData()
|
||||
{
|
||||
Profile::Data ret;
|
||||
datamutex.lock();
|
||||
ret = data;
|
||||
data.Calls = 0;
|
||||
data.Sum = 0;
|
||||
data.Overhead = 0;
|
||||
data.Start = GetTime();
|
||||
datamutex.unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void Profile::Reset()
|
||||
{
|
||||
datamutex.lock();
|
||||
data.Calls = 0;
|
||||
data.Sum = 0;
|
||||
data.Overhead = 0;
|
||||
data.Start = GetTime();
|
||||
datamutex.unlock();
|
||||
}
|
||||
|
||||
|
||||
void Profile::Enter()
|
||||
{
|
||||
EnterTime = GetTime();
|
||||
}
|
||||
|
||||
|
||||
void Profile::Leave()
|
||||
{
|
||||
uint64 LeaveTime = GetTime();
|
||||
datamutex.lock();
|
||||
data.Calls += 1;
|
||||
data.Sum += LeaveTime - EnterTime;
|
||||
datamutex.unlock();
|
||||
}
|
||||
|
||||
|
||||
#else // !USE_PROFILER
|
||||
|
||||
MPT_MSVC_WORKAROUND_LNK4221(Profiler)
|
||||
|
||||
#endif // USE_PROFILER
|
||||
|
||||
|
||||
OPENMPT_NAMESPACE_END
|
Loading…
Add table
Add a link
Reference in a new issue