24 #ifndef PXR_BASE_ARCH_TIMING_H
25 #define PXR_BASE_ARCH_TIMING_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)
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) << 32) + stopLow) -
218 ((uint64_t(_startHigh) << 32) + _startLow);
221 bool _started =
false;
222 uint32_t _startLow = 0, _startHigh = 0;
260 bool _started =
false;
261 uint64_t _startTicks;
318 void const *m, uint64_t (*callM)(
void const *,
int));
333 uint64_t maxTicks = 1e7,
334 bool *reachedConsensus =
nullptr)
336 auto measureN = [&fn](
int nTimes) -> uint64_t {
338 for (
int i = nTimes; i--; ) {
339 std::atomic_signal_fence(std::memory_order_seq_cst);
341 std::atomic_signal_fence(std::memory_order_seq_cst);
346 using MeasureNType = decltype(measureN);
349 maxTicks, reachedConsensus,
350 static_cast<void const *>(&measureN),
351 [](
void const *mN,
int nTimes) {
352 return (*static_cast<MeasureNType const *>(mN))(nTimes);
360 #endif // PXR_BASE_ARCH_TIMING_H
ARCH_API double ArchTicksToSeconds(uint64_t nTicks)
ARCH_API double ArchGetNanosecondsPerTick()
ARCH_API int64_t ArchTicksToNanoseconds(uint64_t nTicks)
**But if you need a result
ARCH_API uint64_t ArchGetIntervalTimerTickOverhead()
uint64_t GetElapsedTicks()
uint64_t GetCurrentTicks()
ArchIntervalTimer(bool start=true)
uint64_t GetStartTicks() const
uint64_t ArchMeasureExecutionTime(Fn const &fn, uint64_t maxTicks=1e7, bool *reachedConsensus=nullptr)
ARCH_API uint64_t ArchSecondsToTicks(double seconds)
PXR_NAMESPACE_OPEN_SCOPE uint64_t ArchGetTickTime()
uint64_t ArchGetStartTickTime()
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
#define PXR_NAMESPACE_CLOSE_SCOPE
uint64_t ArchGetStopTickTime()
ARCH_API uint64_t Arch_MeasureExecutionTime(uint64_t maxTicks, bool *reachedConsensus, void const *m, uint64_t(*callM)(void const *, int))
ARCH_API uint64_t ArchGetTickQuantum()