timestat: Add stopwatch
This commit is contained in:
parent
b4984f5797
commit
5a085560f3
|
@ -64,6 +64,7 @@ HEADERS += \
|
|||
src/base/misc.h \
|
||||
src/base/sort.h \
|
||||
src/base/stack.h \
|
||||
src/base/stopwatch.h \
|
||||
src/base/thread.h \
|
||||
src/ai/search.h \
|
||||
src/base/zobrist.h \
|
||||
|
|
|
@ -122,7 +122,7 @@
|
|||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<ObjectFileName>$(IntDir)</ObjectFileName>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<PreprocessorDefinitions>_WINDOWS;UNICODE;_UNICODE;WIN32;WIN64;QT_NO_DEBUG;NDEBUG;QT_CORE_LIB;QT_GUI_LIB;QT_MULTIMEDIA_LIB;QT_MULTIMEDIAWIDGETS_LIB;QT_NETWORK_LIB;QT_NETWORKAUTH_LIB;QT_WIDGETS_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>_WINDOWS;UNICODE;_UNICODE;WIN32;WIN64;QT_NO_DEBUG;QT_CORE_LIB;QT_GUI_LIB;QT_MULTIMEDIA_LIB;QT_MULTIMEDIAWIDGETS_LIB;QT_NETWORK_LIB;QT_NETWORKAUTH_LIB;QT_WIDGETS_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessToFile>false</PreprocessToFile>
|
||||
<ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
|
@ -158,7 +158,7 @@
|
|||
<QtMoc>
|
||||
<QTDIR>$(QTDIR)</QTDIR>
|
||||
<OutputFile>.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</OutputFile>
|
||||
<Define>_WINDOWS;UNICODE;_UNICODE;WIN32;WIN64;QT_NO_DEBUG;NDEBUG;QT_CORE_LIB;QT_GUI_LIB;QT_MULTIMEDIA_LIB;QT_MULTIMEDIAWIDGETS_LIB;QT_NETWORK_LIB;QT_NETWORKAUTH_LIB;QT_WIDGETS_LIB;%(PreprocessorDefinitions)</Define>
|
||||
<Define>_WINDOWS;UNICODE;_UNICODE;WIN32;WIN64;QT_NO_DEBUG;QT_CORE_LIB;QT_GUI_LIB;QT_MULTIMEDIA_LIB;QT_MULTIMEDIAWIDGETS_LIB;QT_NETWORK_LIB;QT_NETWORKAUTH_LIB;QT_WIDGETS_LIB;%(PreprocessorDefinitions)</Define>
|
||||
<CompilerFlavor>msvc</CompilerFlavor>
|
||||
<Include>$(Configuration)/moc_predefs.h</Include>
|
||||
<ExecutionDescription>Moc'ing %(Identity)...</ExecutionDescription>
|
||||
|
@ -455,6 +455,7 @@
|
|||
<ClInclude Include="src\base\sort.h" />
|
||||
<ClInclude Include="src\base\stack.h" />
|
||||
<QtMoc Include="src\base\thread.h" />
|
||||
<ClInclude Include="src\base\stopwatch.h" />
|
||||
<ClInclude Include="src\base\zobrist.h" />
|
||||
<ClInclude Include="src\game\board.h" />
|
||||
<ClInclude Include="src\game\location.h" />
|
||||
|
|
|
@ -132,6 +132,9 @@
|
|||
<ClInclude Include="src\ai\trainer.h">
|
||||
<Filter>ai</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\base\stopwatch.h">
|
||||
<Filter>base</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CustomBuild Include="debug\moc_predefs.h.cbt">
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
#ifndef STOPWATCH_H_
|
||||
#define STOPWATCH_H_
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <chrono>
|
||||
#include <cstdint>
|
||||
#include <ratio>
|
||||
#ifdef _WIN32
|
||||
#include <intrin.h>
|
||||
#endif
|
||||
|
||||
namespace stopwatch {
|
||||
// An implementation of the 'TrivialClock' concept using the rdtscp instruction.
|
||||
struct rdtscp_clock {
|
||||
using rep = std::uint64_t;
|
||||
using period = std::ratio<1>;
|
||||
using duration = std::chrono::duration<rep, period>;
|
||||
using time_point = std::chrono::time_point<rdtscp_clock, duration>;
|
||||
|
||||
static auto now() noexcept -> time_point
|
||||
{
|
||||
#ifdef _WIN32
|
||||
unsigned int ui;
|
||||
return time_point(duration((static_cast<std::uint64_t>(__rdtscp(&ui)))));
|
||||
#else
|
||||
std::uint32_t hi, lo;
|
||||
__asm__ __volatile__("rdtscp" : "=d"(hi), "=a"(lo));
|
||||
return time_point(duration((static_cast<std::uint64_t>(hi) << 32) | lo));
|
||||
#endif // WIN32
|
||||
}
|
||||
};
|
||||
|
||||
// A timer using the specified clock.
|
||||
template <class Clock = std::chrono::system_clock>
|
||||
struct timer {
|
||||
using time_point = typename Clock::time_point;
|
||||
using duration = typename Clock::duration;
|
||||
|
||||
timer(const duration duration) noexcept : expiry(Clock::now() + duration) {}
|
||||
timer(const time_point expiry) noexcept : expiry(expiry) {}
|
||||
|
||||
bool done(time_point now = Clock::now()) const noexcept {
|
||||
return now >= expiry;
|
||||
}
|
||||
|
||||
auto remaining(time_point now = Clock::now()) const noexcept -> duration {
|
||||
return expiry - now;
|
||||
}
|
||||
|
||||
const time_point expiry;
|
||||
};
|
||||
|
||||
template <class Clock = std::chrono::system_clock>
|
||||
constexpr auto make_timer(typename Clock::duration duration) -> timer<Clock> {
|
||||
return timer<Clock>(duration);
|
||||
}
|
||||
|
||||
// Times how long it takes a function to execute using the specified clock.
|
||||
template <class Clock = rdtscp_clock, class Func>
|
||||
auto time(Func&& function) -> typename Clock::duration {
|
||||
const auto start = Clock::now();
|
||||
function();
|
||||
return Clock::now() - start;
|
||||
}
|
||||
|
||||
// Samples the given function N times using the specified clock.
|
||||
template <std::size_t N, class Clock = rdtscp_clock, class Func>
|
||||
auto sample(Func&& function) -> std::array<typename Clock::duration, N> {
|
||||
std::array<typename Clock::duration, N> samples;
|
||||
|
||||
for (std::size_t i = 0u; i < N; ++i) {
|
||||
samples[i] = time<Clock>(function);
|
||||
}
|
||||
|
||||
std::sort(samples.begin(), samples.end());
|
||||
return samples;
|
||||
}
|
||||
} /* namespace stopwatch */
|
||||
|
||||
#endif // STOPWATCH_H_
|
Loading…
Reference in New Issue