24#ifndef PXR_BASE_ARCH_TIMING_H
25#define PXR_BASE_ARCH_TIMING_H
32#include "pxr/base/arch/api.h"
33#include "pxr/base/arch/defines.h"
39#if defined(ARCH_OS_LINUX) && defined(ARCH_CPU_INTEL)
41#elif defined(ARCH_OS_DARWIN)
42#include <mach/mach_time.h>
43#elif defined(ARCH_OS_WINDOWS)
52PXR_NAMESPACE_OPEN_SCOPE
64#if defined(ARCH_OS_DARWIN)
66 return mach_absolute_time();
67#elif defined(ARCH_CPU_INTEL)
70#elif defined (ARCH_CPU_ARM)
72 __asm __volatile(
"mrs %0, CNTVCT_EL0" :
"=&r" (result));
75#error Unknown architecture.
88#if defined (ARCH_OS_DARWIN)
90#elif defined (ARCH_CPU_ARM)
91 std::atomic_signal_fence(std::memory_order_seq_cst);
92 asm volatile(
"mrs %0, cntvct_el0" :
"=r"(t));
93 std::atomic_signal_fence(std::memory_order_seq_cst);
94#elif defined (ARCH_COMPILER_MSVC)
96 std::atomic_signal_fence(std::memory_order_seq_cst);
99 std::atomic_signal_fence(std::memory_order_seq_cst);
100#elif defined(ARCH_CPU_INTEL) && \
101 (defined(ARCH_COMPILER_CLANG) || defined(ARCH_COMPILER_GCC))
103 std::atomic_signal_fence(std::memory_order_seq_cst);
116#error "Unsupported architecture."
129#if defined (ARCH_OS_DARWIN)
131#elif defined (ARCH_CPU_ARM)
132 std::atomic_signal_fence(std::memory_order_seq_cst);
133 asm volatile(
"mrs %0, cntvct_el0" :
"=r"(t));
134 std::atomic_signal_fence(std::memory_order_seq_cst);
135#elif defined (ARCH_COMPILER_MSVC)
136 std::atomic_signal_fence(std::memory_order_seq_cst);
140 std::atomic_signal_fence(std::memory_order_seq_cst);
141#elif defined(ARCH_CPU_INTEL) && \
142 (defined(ARCH_COMPILER_CLANG) || defined(ARCH_COMPILER_GCC))
143 std::atomic_signal_fence(std::memory_order_seq_cst);
153 :
"rcx",
"rdx",
"cc");
155#error "Unsupported architecture."
160#if defined (doxygen) || \
161 (!defined(ARCH_OS_DARWIN) && defined(ARCH_CPU_INTEL) && \
162 (defined(ARCH_COMPILER_CLANG) || defined(ARCH_COMPILER_GCC)))
179 std::atomic_signal_fence(std::memory_order_seq_cst);
184 :
"=a"(_startLow),
"=d"(_startHigh) :: );
194 return (uint64_t(_startHigh) << 32) + _startLow;
208 uint32_t stopLow, stopHigh;
209 std::atomic_signal_fence(std::memory_order_seq_cst);
213 :
"=a"(stopLow),
"=d"(stopHigh)
217 return (uint64_t(stopHigh - _startHigh) << 32) + (stopLow - _startLow);
220 bool _started =
false;
221 uint32_t _startLow = 0, _startHigh = 0;
259 bool _started =
false;
260 uint64_t _startTicks;
316Arch_MeasureExecutionTime(uint64_t maxMicroseconds,
bool *reachedConsensus,
317 void const *m, uint64_t (*callM)(
void const *,
int));
332 uint64_t maxMicroSeconds = 10000,
333 bool *reachedConsensus =
nullptr)
335 auto measureN = [&fn](
int nTimes) -> uint64_t {
337 for (
int i = nTimes; i--; ) {
338 std::atomic_signal_fence(std::memory_order_seq_cst);
340 std::atomic_signal_fence(std::memory_order_seq_cst);
345 using MeasureNType =
decltype(measureN);
347 return Arch_MeasureExecutionTime(
348 maxMicroSeconds, reachedConsensus,
349 static_cast<void const *
>(&measureN),
350 [](
void const *mN,
int nTimes) {
351 return (*
static_cast<MeasureNType
const *
>(mN))(nTimes);
357PXR_NAMESPACE_CLOSE_SCOPE
uint64_t ArchMeasureExecutionTime(Fn const &fn, uint64_t maxMicroSeconds=10000, bool *reachedConsensus=nullptr)
Run fn repeatedly attempting to determine a consensus fastest execution time with low noise,...
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.
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.
uint64_t GetCurrentTicks()
Read and return the current time.
void Start()
Start the timer, or reset the start time if it has already been started.
uint64_t GetStartTicks() const
Return this timer's start time, or 0 if it hasn't been started.
uint64_t GetElapsedTicks()
Read the current time and return the difference between it and the start time.
ArchIntervalTimer(bool start=true)
Construct a timer and start timing if start is true.
bool IsStarted() const
Return true if this timer is started.