mirror of
https://github.com/yuzu-emu/FasTC.git
synced 2025-01-07 01:55:37 +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...
|
||||
SET( HEADERS ${HEADERS} "src/StopWatch.h" )
|
||||
IF( MSVC )
|
||||
|
||||
IF( WIN32 )
|
||||
SET( SOURCES ${SOURCES} "src/StopWatchWin32.cpp" )
|
||||
ELSEIF( APPLE )
|
||||
SET( SOURCES ${SOURCES} "src/StopWatchOSX.cpp" )
|
||||
ELSE()
|
||||
SET( SOURCES ${SOURCES} "src/StopWatchUnix.cpp" )
|
||||
ENDIF()
|
||||
|
|
|
@ -15,15 +15,20 @@
|
|||
//
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "TexCompTypes.h"
|
||||
// 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...
|
||||
class StopWatchImpl;
|
||||
|
||||
// A simple stopwatch class using Windows' high-resolution performance counters.
|
||||
class StopWatch
|
||||
{
|
||||
public:
|
||||
StopWatch();
|
||||
StopWatch(const StopWatch &);
|
||||
|
||||
~StopWatch();
|
||||
|
||||
StopWatch &operator=(const StopWatch &);
|
||||
|
||||
void Start();
|
||||
void Stop();
|
||||
|
@ -34,8 +39,5 @@ public:
|
|||
double TimeInMicroseconds() const;
|
||||
|
||||
private:
|
||||
uint64 frequency;
|
||||
uint64 start;
|
||||
uint64 stop;
|
||||
int32_ptr affinityMask;
|
||||
StopWatchImpl *impl;
|
||||
};
|
||||
|
|
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 "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() {
|
||||
|
||||
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &(impl->ts));
|
||||
impl->timer = double(ts.tv_sec) + 1e-9 * double(ts.tv_nsec);
|
||||
}
|
||||
|
||||
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() {
|
||||
|
||||
impl->timer = impl->duration = 0.0;
|
||||
memset(impl->ts, 0, sizeof(timespec));
|
||||
}
|
||||
|
||||
double StopWatch::TimeInSeconds() const {
|
||||
|
||||
return impl->duration;
|
||||
}
|
||||
|
||||
double StopWatch::TimeInMilliseconds() const {
|
||||
|
||||
return impl->duration * 1000;
|
||||
}
|
||||
|
||||
double StopWatch::TimeInMicroseconds() const {
|
||||
|
||||
return impl->duration * 1000000;
|
||||
}
|
||||
|
|
|
@ -16,91 +16,113 @@
|
|||
//--------------------------------------------------------------------------------------
|
||||
|
||||
#include "StopWatch.h"
|
||||
#include "TexCompTypes.h"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
// Initialize member variables.
|
||||
StopWatch::StopWatch() :
|
||||
frequency(0),
|
||||
start(0),
|
||||
stop(0),
|
||||
affinityMask(0)
|
||||
{
|
||||
// Initialize the performance counter frequency.
|
||||
LARGE_INTEGER perfQuery;
|
||||
BOOL supported = QueryPerformanceFrequency(&perfQuery);
|
||||
assert(supported == TRUE);
|
||||
this->frequency = perfQuery.QuadPart;
|
||||
class StopWatchImpl {
|
||||
uint64 frequency;
|
||||
uint64 start;
|
||||
uint64 stop;
|
||||
uintptr affinityMask;
|
||||
|
||||
StopWatchImpl() :
|
||||
start(0), stop(0), affinityMask(0)
|
||||
{
|
||||
// Initialize the performance counter frequency.
|
||||
LARGE_INTEGER perfQuery;
|
||||
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.
|
||||
void StopWatch::Start()
|
||||
{
|
||||
// MSDN recommends setting the thread affinity to avoid bugs in the BIOS and HAL.
|
||||
// Create an affinity mask for the current processor.
|
||||
affinityMask = (DWORD_PTR)1 << GetCurrentProcessorNumber();
|
||||
HANDLE currThread = GetCurrentThread();
|
||||
DWORD_PTR prevAffinityMask = SetThreadAffinityMask(currThread, affinityMask);
|
||||
assert(prevAffinityMask != 0);
|
||||
// MSDN recommends setting the thread affinity to avoid bugs in the BIOS and HAL.
|
||||
// Create an affinity mask for the current processor.
|
||||
impl->affinityMask = (DWORD_PTR)1 << GetCurrentProcessorNumber();
|
||||
HANDLE currThread = GetCurrentThread();
|
||||
DWORD_PTR prevAffinityMask = SetThreadAffinityMask(currThread, impl->affinityMask);
|
||||
assert(prevAffinityMask != 0);
|
||||
|
||||
// Query the performance counter.
|
||||
LARGE_INTEGER perfQuery;
|
||||
BOOL result = QueryPerformanceCounter(&perfQuery);
|
||||
assert(result);
|
||||
start = perfQuery.QuadPart;
|
||||
// Query the performance counter.
|
||||
LARGE_INTEGER perfQuery;
|
||||
BOOL result = QueryPerformanceCounter(&perfQuery);
|
||||
assert(result);
|
||||
impl->start = perfQuery.QuadPart;
|
||||
|
||||
// Restore the thread's affinity mask.
|
||||
prevAffinityMask = SetThreadAffinityMask(currThread, prevAffinityMask);
|
||||
assert(prevAffinityMask != 0);
|
||||
// Restore the thread's affinity mask.
|
||||
prevAffinityMask = SetThreadAffinityMask(currThread, prevAffinityMask);
|
||||
assert(prevAffinityMask != 0);
|
||||
}
|
||||
|
||||
// Stop the stopwatch.
|
||||
void StopWatch::Stop()
|
||||
{
|
||||
// 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.
|
||||
HANDLE currThread = GetCurrentThread();
|
||||
DWORD_PTR prevAffinityMask = SetThreadAffinityMask(currThread, affinityMask);
|
||||
assert(prevAffinityMask != 0);
|
||||
// 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.
|
||||
HANDLE currThread = GetCurrentThread();
|
||||
DWORD_PTR prevAffinityMask = SetThreadAffinityMask(currThread, impl->affinityMask);
|
||||
assert(prevAffinityMask != 0);
|
||||
|
||||
// Query the performance counter.
|
||||
LARGE_INTEGER perfQuery;
|
||||
BOOL result = QueryPerformanceCounter(&perfQuery);
|
||||
assert(result);
|
||||
stop = perfQuery.QuadPart;
|
||||
// Query the performance counter.
|
||||
LARGE_INTEGER perfQuery;
|
||||
BOOL result = QueryPerformanceCounter(&perfQuery);
|
||||
assert(result);
|
||||
impl->stop = perfQuery.QuadPart;
|
||||
|
||||
// Restore the thread's affinity mask.
|
||||
prevAffinityMask = SetThreadAffinityMask(currThread, prevAffinityMask);
|
||||
assert(prevAffinityMask != 0);
|
||||
// Restore the thread's affinity mask.
|
||||
prevAffinityMask = SetThreadAffinityMask(currThread, prevAffinityMask);
|
||||
assert(prevAffinityMask != 0);
|
||||
}
|
||||
|
||||
// Reset the stopwatch.
|
||||
void StopWatch::Reset()
|
||||
{
|
||||
start = 0;
|
||||
stop = 0;
|
||||
affinityMask = 0;
|
||||
impl->start = 0;
|
||||
impl->stop = 0;
|
||||
impl->affinityMask = 0;
|
||||
}
|
||||
|
||||
// Get the elapsed time in seconds.
|
||||
double StopWatch::TimeInSeconds() const
|
||||
{
|
||||
// Return the elapsed time in seconds.
|
||||
assert((stop - start) > 0);
|
||||
return double(stop - start) / double(frequency);
|
||||
// Return the elapsed time in seconds.
|
||||
assert((impl->stop - impl->start) > 0);
|
||||
return double(impl->stop - impl->start) / double(frequency);
|
||||
}
|
||||
|
||||
// Get the elapsed time in milliseconds.
|
||||
double StopWatch::TimeInMilliseconds() const
|
||||
{
|
||||
// Return the elapsed time in milliseconds.
|
||||
assert((stop - start) > 0);
|
||||
return double(stop - start) / double(frequency) * 1000.0;
|
||||
// Return the elapsed time in milliseconds.
|
||||
assert((impl->stop - impl->start) > 0);
|
||||
return double(impl->stop - impl->start) / double(frequency) * 1000.0;
|
||||
}
|
||||
|
||||
// Get the elapsed time in microseconds.
|
||||
double StopWatch::TimeInMicroseconds() const
|
||||
{
|
||||
// Return the elapsed time in microseconds.
|
||||
assert((stop - start) > 0);
|
||||
return double(stop - start) / double(frequency) * 1000000.0;
|
||||
// Return the elapsed time in microseconds.
|
||||
assert((impl->stop - impl->start) > 0);
|
||||
return double(impl->stop - impl->start) / double(impl->frequency) * 1000000.0;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue