7#ifndef PXR_BASE_ARCH_TIMING_H
8#define PXR_BASE_ARCH_TIMING_H
15#include "pxr/base/arch/api.h"
16#include "pxr/base/arch/defines.h"
23#if defined(PXR_ARCH_PREFER_TSC_TIMING) && \
24 defined(ARCH_OS_LINUX) && \
25 defined(ARCH_CPU_INTEL) && \
26 (defined(ARCH_COMPILER_CLANG) || defined(ARCH_COMPILER_GCC))
27#define ARCH_USE_TSC_TIMING 1
29#define ARCH_USE_TSC_TIMING 0
32#if ARCH_USE_TSC_TIMING
48PXR_NAMESPACE_OPEN_SCOPE
51#if !ARCH_USE_TSC_TIMING
56using Arch_TimingClock = std::chrono::steady_clock;
69#if ARCH_USE_TSC_TIMING
72 return Arch_TimingClock::now().time_since_epoch().count();
86#if ARCH_USE_TSC_TIMING
89 std::atomic_signal_fence(std::memory_order_seq_cst);
104 std::atomic_signal_fence(std::memory_order_seq_cst);
106 std::atomic_signal_fence(std::memory_order_seq_cst);
122#if ARCH_USE_TSC_TIMING
125 std::atomic_signal_fence(std::memory_order_seq_cst);
135 :
"rcx",
"rdx",
"cc");
139 std::atomic_signal_fence(std::memory_order_seq_cst);
141 std::atomic_signal_fence(std::memory_order_seq_cst);
164 bool IsStarted()
const {
168 uint64_t GetStartTicks()
const {
172 uint64_t GetCurrentTicks() {
176 uint64_t GetElapsedTicks() {
183 bool _started =
false;
184 uint64_t _startTicks;
208#if defined(doxygen) || ARCH_USE_TSC_TIMING
214 return 1e+9 * Arch_TimingClock::period::num / Arch_TimingClock::period::den;
229#if defined(doxygen) || ARCH_USE_TSC_TIMING
235 return static_cast<int64_t
>(
242#if defined(doxygen) || ARCH_USE_TSC_TIMING
254#if defined(doxygen) || ARCH_USE_TSC_TIMING
266Arch_MeasureExecutionTime(uint64_t maxTicks,
bool *reachedConsensus,
267 void const *m, uint64_t (*callM)(
void const *,
int));
282 uint64_t maxTicks = 1e7,
283 bool *reachedConsensus =
nullptr)
285 auto measureN = [&fn](
int nTimes) -> uint64_t {
287 for (
int i = nTimes; i--; ) {
288 std::atomic_signal_fence(std::memory_order_seq_cst);
290 std::atomic_signal_fence(std::memory_order_seq_cst);
292 return iTimer.GetElapsedTicks();
295 using MeasureNType =
decltype(measureN);
297 return Arch_MeasureExecutionTime(
298 maxTicks, reachedConsensus,
299 static_cast<void const *
>(&measureN),
300 [](
void const *mN,
int nTimes) {
301 return (*
static_cast<MeasureNType
const *
>(mN))(nTimes);
307PXR_NAMESPACE_CLOSE_SCOPE
uint64_t ArchGetTickTime()
Return the current time in system-dependent units.
ARCH_API uint64_t ArchGetTickQuantum()
Return the tick time resolution.
uint64_t ArchGetStartTickTime()
Get a "start" tick time for measuring an interval of time, followed by a later call to ArchGetStopTic...
ARCH_API uint64_t ArchGetIntervalTimerTickOverhead()
Return the ticks taken to record an interval of time with ArchIntervalTimer, as measured at startup t...
ARCH_API double ArchGetNanosecondsPerTick()
Get nanoseconds per tick.
uint64_t ArchGetStopTickTime()
Get a "stop" tick time for measuring an interval of time.
uint64_t ArchMeasureExecutionTime(Fn const &fn, uint64_t maxTicks=1e7, bool *reachedConsensus=nullptr)
Run fn repeatedly attempting to determine a consensus fastest execution time with low noise,...
ARCH_API double ArchTicksToSeconds(uint64_t nTicks)
Convert a duration measured in "ticks", as returned by ArchGetTickTime(), to seconds.
ARCH_API uint64_t ArchSecondsToTicks(double seconds)
Convert a duration in seconds to "ticks", as returned by ArchGetTickTime().
ARCH_API int64_t ArchTicksToNanoseconds(uint64_t nTicks)
Convert a duration measured in "ticks", as returned by ArchGetTickTime(), to nanoseconds.
A simple timer class for measuring an interval of time using the ArchTickTimer facilities.