mirror of
https://github.com/yuzu-emu/FasTC.git
synced 2025-01-23 19:01:03 +00:00
Fix timing functions for various platforms.
This commit is contained in:
parent
720ad0ac6f
commit
d8fc05a763
|
@ -12,8 +12,11 @@ SET( HEADERS
|
||||||
|
|
||||||
# Make sure to add the appropriate stopwatch files...
|
# Make sure to add the appropriate stopwatch files...
|
||||||
SET( HEADERS ${HEADERS} "src/StopWatch.h" )
|
SET( HEADERS ${HEADERS} "src/StopWatch.h" )
|
||||||
IF( MSVC )
|
|
||||||
|
IF( WIN32 )
|
||||||
SET( SOURCES ${SOURCES} "src/StopWatchWin32.cpp" )
|
SET( SOURCES ${SOURCES} "src/StopWatchWin32.cpp" )
|
||||||
|
ELSEIF( APPLE )
|
||||||
|
SET( SOURCES ${SOURCES} "src/StopWatchOSX.cpp" )
|
||||||
ELSE()
|
ELSE()
|
||||||
SET( SOURCES ${SOURCES} "src/StopWatchUnix.cpp" )
|
SET( SOURCES ${SOURCES} "src/StopWatchUnix.cpp" )
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
|
@ -15,15 +15,20 @@
|
||||||
//
|
//
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
#pragma once
|
// Forward declare the private implementation of the class that will actually implement
|
||||||
|
// the timing features. This class is defined in each module depending on the platform...
|
||||||
#include "TexCompTypes.h"
|
class StopWatchImpl;
|
||||||
|
|
||||||
// A simple stopwatch class using Windows' high-resolution performance counters.
|
// A simple stopwatch class using Windows' high-resolution performance counters.
|
||||||
class StopWatch
|
class StopWatch
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
StopWatch();
|
StopWatch();
|
||||||
|
StopWatch(const StopWatch &);
|
||||||
|
|
||||||
|
~StopWatch();
|
||||||
|
|
||||||
|
StopWatch &operator=(const StopWatch &);
|
||||||
|
|
||||||
void Start();
|
void Start();
|
||||||
void Stop();
|
void Stop();
|
||||||
|
@ -34,8 +39,5 @@ public:
|
||||||
double TimeInMicroseconds() const;
|
double TimeInMicroseconds() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint64 frequency;
|
StopWatchImpl *impl;
|
||||||
uint64 start;
|
|
||||||
uint64 stop;
|
|
||||||
int32_ptr affinityMask;
|
|
||||||
};
|
};
|
||||||
|
|
67
Core/src/StopWatchOSX.cpp
Normal file
67
Core/src/StopWatchOSX.cpp
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
#include "StopWatch.h"
|
||||||
|
#include "TexCompTypes.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <mach/mach_time.h>
|
||||||
|
|
||||||
|
class StopWatchImpl {
|
||||||
|
public:
|
||||||
|
uint64 start;
|
||||||
|
|
||||||
|
double resolution;
|
||||||
|
double duration;
|
||||||
|
|
||||||
|
StopWatchImpl() {
|
||||||
|
mach_timebase_info_data_t info;
|
||||||
|
mach_timebase_info(&info);
|
||||||
|
|
||||||
|
resolution = double(info.numer) / double(info.denom);
|
||||||
|
resolution *= 1e-9;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
StopWatch::StopWatch(const StopWatch &other) {
|
||||||
|
impl = new StopWatchImpl();
|
||||||
|
memcpy(impl, other.impl, sizeof(StopWatchImpl));
|
||||||
|
}
|
||||||
|
|
||||||
|
StopWatch &StopWatch::operator=(const StopWatch &other) {
|
||||||
|
if(impl) {
|
||||||
|
delete impl;
|
||||||
|
}
|
||||||
|
impl = new StopWatchImpl();
|
||||||
|
memcpy(impl, other.impl, sizeof(StopWatchImpl));
|
||||||
|
}
|
||||||
|
|
||||||
|
StopWatch::~StopWatch() {
|
||||||
|
delete impl;
|
||||||
|
}
|
||||||
|
|
||||||
|
StopWatch::StopWatch() : impl(new StopWatchImpl) {
|
||||||
|
Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void StopWatch::Start() {
|
||||||
|
impl->start = mach_absolute_time();
|
||||||
|
}
|
||||||
|
|
||||||
|
void StopWatch::Stop() {
|
||||||
|
impl->duration = impl->resolution * (double(mach_absolute_time()) - impl->start);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StopWatch::Reset() {
|
||||||
|
impl->start = impl->duration = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
double StopWatch::TimeInSeconds() const {
|
||||||
|
return impl->duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
double StopWatch::TimeInMilliseconds() const {
|
||||||
|
return impl->duration * 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
double StopWatch::TimeInMicroseconds() const {
|
||||||
|
return impl->duration * 1000000;
|
||||||
|
}
|
|
@ -1,29 +1,62 @@
|
||||||
#include "StopWatch.h"
|
#include "StopWatch.h"
|
||||||
|
#include "TexCompTypes.h"
|
||||||
|
|
||||||
StopWatch::StopWatch() {
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
class StopWatchImpl {
|
||||||
|
public:
|
||||||
|
timespec ts;
|
||||||
|
|
||||||
|
double timer;
|
||||||
|
double duration;
|
||||||
|
};
|
||||||
|
|
||||||
|
StopWatch::StopWatch(const StopWatch &other) {
|
||||||
|
impl = new StopWatchImpl();
|
||||||
|
memcpy(impl, other.impl, sizeof(StopWatchImpl));
|
||||||
|
}
|
||||||
|
|
||||||
|
StopWatch &StopWatch::operator=(const StopWatch &other) {
|
||||||
|
if(impl) {
|
||||||
|
delete impl;
|
||||||
|
}
|
||||||
|
impl = new StopWatchImpl();
|
||||||
|
memcpy(impl, other.impl. sizeof(StopWatchImpl));
|
||||||
|
}
|
||||||
|
|
||||||
|
StopWatch::~StopWatch() {
|
||||||
|
delete impl;
|
||||||
|
}
|
||||||
|
|
||||||
|
StopWatch::StopWatch() : impl(new StopWatchImpl) {
|
||||||
|
Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void StopWatch::Start() {
|
void StopWatch::Start() {
|
||||||
|
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &(impl->ts));
|
||||||
|
impl->timer = double(ts.tv_sec) + 1e-9 * double(ts.tv_nsec);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StopWatch::Stop() {
|
void StopWatch::Stop() {
|
||||||
|
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &(impl->ts));
|
||||||
|
impl->duration = -(impl->timer) + (double(ts.tv_sec) + 1e-9 * double(ts.tv_nsec));
|
||||||
}
|
}
|
||||||
|
|
||||||
void StopWatch::Reset() {
|
void StopWatch::Reset() {
|
||||||
|
impl->timer = impl->duration = 0.0;
|
||||||
|
memset(impl->ts, 0, sizeof(timespec));
|
||||||
}
|
}
|
||||||
|
|
||||||
double StopWatch::TimeInSeconds() const {
|
double StopWatch::TimeInSeconds() const {
|
||||||
|
return impl->duration;
|
||||||
}
|
}
|
||||||
|
|
||||||
double StopWatch::TimeInMilliseconds() const {
|
double StopWatch::TimeInMilliseconds() const {
|
||||||
|
return impl->duration * 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
double StopWatch::TimeInMicroseconds() const {
|
double StopWatch::TimeInMicroseconds() const {
|
||||||
|
return impl->duration * 1000000;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,91 +16,113 @@
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
#include "StopWatch.h"
|
#include "StopWatch.h"
|
||||||
|
#include "TexCompTypes.h"
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
// Initialize member variables.
|
class StopWatchImpl {
|
||||||
StopWatch::StopWatch() :
|
uint64 frequency;
|
||||||
frequency(0),
|
uint64 start;
|
||||||
start(0),
|
uint64 stop;
|
||||||
stop(0),
|
uintptr affinityMask;
|
||||||
affinityMask(0)
|
|
||||||
{
|
StopWatchImpl() :
|
||||||
// Initialize the performance counter frequency.
|
start(0), stop(0), affinityMask(0)
|
||||||
LARGE_INTEGER perfQuery;
|
{
|
||||||
BOOL supported = QueryPerformanceFrequency(&perfQuery);
|
// Initialize the performance counter frequency.
|
||||||
assert(supported == TRUE);
|
LARGE_INTEGER perfQuery;
|
||||||
this->frequency = perfQuery.QuadPart;
|
BOOL supported = QueryPerformanceFrequency(&perfQuery);
|
||||||
|
assert(supported == TRUE);
|
||||||
|
this->frequency = perfQuery.QuadPart;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
StopWatch::StopWatch(const StopWatch &other) {
|
||||||
|
impl = new StopWatchImpl();
|
||||||
|
memcpy(impl, other.impl, sizeof(StopWatchImpl));
|
||||||
|
}
|
||||||
|
|
||||||
|
StopWatch &StopWatch::operator=(const StopWatch &other) {
|
||||||
|
if(impl) {
|
||||||
|
delete impl;
|
||||||
|
}
|
||||||
|
impl = new StopWatchImpl();
|
||||||
|
memcpy(impl, other.impl. sizeof(StopWatchImpl));
|
||||||
|
}
|
||||||
|
|
||||||
|
StopWatch::~StopWatch() {
|
||||||
|
delete impl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start the stopwatch.
|
// Start the stopwatch.
|
||||||
void StopWatch::Start()
|
void StopWatch::Start()
|
||||||
{
|
{
|
||||||
// MSDN recommends setting the thread affinity to avoid bugs in the BIOS and HAL.
|
// MSDN recommends setting the thread affinity to avoid bugs in the BIOS and HAL.
|
||||||
// Create an affinity mask for the current processor.
|
// Create an affinity mask for the current processor.
|
||||||
affinityMask = (DWORD_PTR)1 << GetCurrentProcessorNumber();
|
impl->affinityMask = (DWORD_PTR)1 << GetCurrentProcessorNumber();
|
||||||
HANDLE currThread = GetCurrentThread();
|
HANDLE currThread = GetCurrentThread();
|
||||||
DWORD_PTR prevAffinityMask = SetThreadAffinityMask(currThread, affinityMask);
|
DWORD_PTR prevAffinityMask = SetThreadAffinityMask(currThread, impl->affinityMask);
|
||||||
assert(prevAffinityMask != 0);
|
assert(prevAffinityMask != 0);
|
||||||
|
|
||||||
// Query the performance counter.
|
// Query the performance counter.
|
||||||
LARGE_INTEGER perfQuery;
|
LARGE_INTEGER perfQuery;
|
||||||
BOOL result = QueryPerformanceCounter(&perfQuery);
|
BOOL result = QueryPerformanceCounter(&perfQuery);
|
||||||
assert(result);
|
assert(result);
|
||||||
start = perfQuery.QuadPart;
|
impl->start = perfQuery.QuadPart;
|
||||||
|
|
||||||
// Restore the thread's affinity mask.
|
// Restore the thread's affinity mask.
|
||||||
prevAffinityMask = SetThreadAffinityMask(currThread, prevAffinityMask);
|
prevAffinityMask = SetThreadAffinityMask(currThread, prevAffinityMask);
|
||||||
assert(prevAffinityMask != 0);
|
assert(prevAffinityMask != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop the stopwatch.
|
// Stop the stopwatch.
|
||||||
void StopWatch::Stop()
|
void StopWatch::Stop()
|
||||||
{
|
{
|
||||||
// MSDN recommends setting the thread affinity to avoid bugs in the BIOS and HAL.
|
// MSDN recommends setting the thread affinity to avoid bugs in the BIOS and HAL.
|
||||||
// Use the affinity mask that was created in the Start function.
|
// Use the affinity mask that was created in the Start function.
|
||||||
HANDLE currThread = GetCurrentThread();
|
HANDLE currThread = GetCurrentThread();
|
||||||
DWORD_PTR prevAffinityMask = SetThreadAffinityMask(currThread, affinityMask);
|
DWORD_PTR prevAffinityMask = SetThreadAffinityMask(currThread, impl->affinityMask);
|
||||||
assert(prevAffinityMask != 0);
|
assert(prevAffinityMask != 0);
|
||||||
|
|
||||||
// Query the performance counter.
|
// Query the performance counter.
|
||||||
LARGE_INTEGER perfQuery;
|
LARGE_INTEGER perfQuery;
|
||||||
BOOL result = QueryPerformanceCounter(&perfQuery);
|
BOOL result = QueryPerformanceCounter(&perfQuery);
|
||||||
assert(result);
|
assert(result);
|
||||||
stop = perfQuery.QuadPart;
|
impl->stop = perfQuery.QuadPart;
|
||||||
|
|
||||||
// Restore the thread's affinity mask.
|
// Restore the thread's affinity mask.
|
||||||
prevAffinityMask = SetThreadAffinityMask(currThread, prevAffinityMask);
|
prevAffinityMask = SetThreadAffinityMask(currThread, prevAffinityMask);
|
||||||
assert(prevAffinityMask != 0);
|
assert(prevAffinityMask != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset the stopwatch.
|
// Reset the stopwatch.
|
||||||
void StopWatch::Reset()
|
void StopWatch::Reset()
|
||||||
{
|
{
|
||||||
start = 0;
|
impl->start = 0;
|
||||||
stop = 0;
|
impl->stop = 0;
|
||||||
affinityMask = 0;
|
impl->affinityMask = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the elapsed time in seconds.
|
// Get the elapsed time in seconds.
|
||||||
double StopWatch::TimeInSeconds() const
|
double StopWatch::TimeInSeconds() const
|
||||||
{
|
{
|
||||||
// Return the elapsed time in seconds.
|
// Return the elapsed time in seconds.
|
||||||
assert((stop - start) > 0);
|
assert((impl->stop - impl->start) > 0);
|
||||||
return double(stop - start) / double(frequency);
|
return double(impl->stop - impl->start) / double(frequency);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the elapsed time in milliseconds.
|
// Get the elapsed time in milliseconds.
|
||||||
double StopWatch::TimeInMilliseconds() const
|
double StopWatch::TimeInMilliseconds() const
|
||||||
{
|
{
|
||||||
// Return the elapsed time in milliseconds.
|
// Return the elapsed time in milliseconds.
|
||||||
assert((stop - start) > 0);
|
assert((impl->stop - impl->start) > 0);
|
||||||
return double(stop - start) / double(frequency) * 1000.0;
|
return double(impl->stop - impl->start) / double(frequency) * 1000.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the elapsed time in microseconds.
|
// Get the elapsed time in microseconds.
|
||||||
double StopWatch::TimeInMicroseconds() const
|
double StopWatch::TimeInMicroseconds() const
|
||||||
{
|
{
|
||||||
// Return the elapsed time in microseconds.
|
// Return the elapsed time in microseconds.
|
||||||
assert((stop - start) > 0);
|
assert((impl->stop - impl->start) > 0);
|
||||||
return double(stop - start) / double(frequency) * 1000000.0;
|
return double(impl->stop - impl->start) / double(impl->frequency) * 1000000.0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue