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) 40 #include <x86intrin.h> 41 #elif defined(ARCH_OS_DARWIN) 42 #include <mach/mach_time.h> 43 #elif defined(ARCH_OS_WINDOWS) 52 PXR_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;
316 Arch_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);
357 PXR_NAMESPACE_CLOSE_SCOPE
359 #endif // PXR_BASE_ARCH_TIMING_H ARCH_API double ArchTicksToSeconds(uint64_t nTicks)
Convert a duration measured in "ticks", as returned by ArchGetTickTime(), to seconds.
uint64_t ArchGetTickTime()
Return the current time in system-dependent units.
ARCH_API double ArchGetNanosecondsPerTick()
Get nanoseconds per tick.
ARCH_API int64_t ArchTicksToNanoseconds(uint64_t nTicks)
Convert a duration measured in "ticks", as returned by ArchGetTickTime(), to nanoseconds.
ARCH_API uint64_t ArchGetIntervalTimerTickOverhead()
Return the ticks taken to record an interval of time with ArchIntervalTimer, as measured at startup t...
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 GetCurrentTicks()
Read and return the current time.
bool IsStarted() const
Return true if this timer is started.
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.
ARCH_API uint64_t ArchSecondsToTicks(double seconds)
Convert a duration in seconds to "ticks", as returned by ArchGetTickTime().
A simple timer class for measuring an interval of time using the ArchTickTimer facilities.
uint64_t ArchGetStartTickTime()
Get a "start" tick time for measuring an interval of time, followed by a later call to ArchGetStopTic...
uint64_t GetElapsedTicks()
Read the current time and return the difference between it and the start time.
uint64_t ArchGetStopTickTime()
Get a "stop" tick time for measuring an interval of time.
ArchIntervalTimer(bool start=true)
Construct a timer and start timing if start is true.
ARCH_API uint64_t ArchGetTickQuantum()
Return the tick time resolution.