1
0
mirror of https://github.com/wolfpld/tracy.git synced 2025-03-20 07:40:02 +08:00

Test if HW timer can be used on arm.

This commit is contained in:
Bartosz Taudul 2018-04-27 16:58:45 +02:00
parent 6a2311a7b7
commit 237aee30a8
2 changed files with 86 additions and 23 deletions

View File

@ -35,6 +35,11 @@
#define init_order(x) #define init_order(x)
#endif #endif
#if defined TRACY_HW_TIMER && __ARM_ARCH >= 6
# include <signal.h>
# include <setjmp.h>
#endif
namespace tracy namespace tracy
{ {
@ -53,6 +58,69 @@ struct InitTimeWrapper
int64_t val; int64_t val;
}; };
#if defined TRACY_HW_TIMER && __ARM_ARCH >= 6
int64_t (*GetTimeImpl)();
int64_t GetTimeImplFallback()
{
return std::chrono::duration_cast<std::chrono::nanoseconds>( std::chrono::high_resolution_clock::now().time_since_epoch() ).count();
}
int64_t GetTimeImplCntvct()
{
int64_t t;
# ifdef __aarch64__
asm volatile ( "mrs %0, cntvct_el0" : "=r" (t) );
# else
asm volatile ( "mrrc p15, 1, %Q0, %R0, c14" : "=r" (t) );
# endif
return t;
}
static sigjmp_buf SigIllEnv;
static int SetupHwTimerFailed()
{
return sigsetjmp( SigIllEnv, 1 );
}
static void SetupHwTimerSigIllHandler( int signum )
{
siglongjmp( SigIllEnv, 1 );
}
static int64_t SetupHwTimer()
{
struct sigaction act, oldact;
memset( &act, 0, sizeof( act ) );
act.sa_handler = SetupHwTimerSigIllHandler;
if( sigaction( SIGILL, &act, &oldact ) )
{
GetTimeImpl = GetTimeImplFallback;
return Profiler::GetTime();
}
if( SetupHwTimerFailed() )
{
sigaction( SIGILL, &oldact, nullptr );
GetTimeImpl = GetTimeImplFallback;
return Profiler::GetTime();
}
GetTimeImplCntvct();
sigaction( SIGILL, &oldact, nullptr );
GetTimeImpl = GetTimeImplCntvct;
return Profiler::GetTime();
}
#else
static int64_t SetupHwTimer()
{
return Profiler::GetTime();
}
#endif
static const char* GetProcessName() static const char* GetProcessName()
{ {
#if defined _MSC_VER #if defined _MSC_VER
@ -96,7 +164,7 @@ thread_local ProducerWrapper init_order(108) s_token { s_queue.get_explicit_prod
# pragma init_seg( ".CRT$XCB" ) # pragma init_seg( ".CRT$XCB" )
#endif #endif
static InitTimeWrapper init_order(101) s_initTime { Profiler::GetTime() }; static InitTimeWrapper init_order(101) s_initTime { SetupHwTimer() };
static RPMallocInit init_order(102) s_rpmalloc_init; static RPMallocInit init_order(102) s_rpmalloc_init;
moodycamel::ConcurrentQueue<QueueItem> init_order(103) s_queue( QueuePrealloc ); moodycamel::ConcurrentQueue<QueueItem> init_order(103) s_queue( QueuePrealloc );
std::atomic<uint32_t> init_order(104) s_lockCounter( 0 ); std::atomic<uint32_t> init_order(104) s_lockCounter( 0 );
@ -498,6 +566,14 @@ bool Profiler::HandleServerQuery()
void Profiler::CalibrateTimer() void Profiler::CalibrateTimer()
{ {
#ifdef TRACY_HW_TIMER #ifdef TRACY_HW_TIMER
# if __ARM_ARCH >= 6
if( GetTimeImpl == GetTimeImplFallback )
{
m_timerMul = 1.;
return;
}
# endif
std::atomic_signal_fence( std::memory_order_acq_rel ); std::atomic_signal_fence( std::memory_order_acq_rel );
const auto t0 = std::chrono::high_resolution_clock::now(); const auto t0 = std::chrono::high_resolution_clock::now();
const auto r0 = GetTime(); const auto r0 = GetTime();

View File

@ -19,11 +19,7 @@
# include <intrin.h> # include <intrin.h>
#endif #endif
#if defined _MSC_VER || defined __CYGWIN__ || ( ( defined __i386 || defined _M_IX86 || defined __x86_64__ || defined _M_X64 ) && !defined __ANDROID__ ) #if defined _MSC_VER || defined __CYGWIN__ || ( ( defined __i386 || defined _M_IX86 || defined __x86_64__ || defined _M_X64 ) && !defined __ANDROID__ ) || __ARM_ARCH >= 6
# define TRACY_HW_TIMER
#endif
#if defined __aarch64__ || __ARM_ARCH >= 6
# define TRACY_HW_TIMER # define TRACY_HW_TIMER
#endif #endif
@ -56,6 +52,10 @@ struct GpuCtxWrapper
using Magic = moodycamel::ConcurrentQueueDefaultTraits::index_t; using Magic = moodycamel::ConcurrentQueueDefaultTraits::index_t;
#if __ARM_ARCH >= 6
extern int64_t (*GetTimeImpl)();
#endif
class Profiler; class Profiler;
extern Profiler s_profiler; extern Profiler s_profiler;
@ -68,16 +68,9 @@ public:
static tracy_force_inline int64_t GetTime( uint32_t& cpu ) static tracy_force_inline int64_t GetTime( uint32_t& cpu )
{ {
#ifdef TRACY_HW_TIMER #ifdef TRACY_HW_TIMER
# if defined __aarch64__ # if __ARM_ARCH >= 6
int64_t t;
cpu = 0xFFFFFFFF; cpu = 0xFFFFFFFF;
asm volatile ( "mrs %0, cntvct_el0" : "=r" (t) ); return GetTimeImpl();
return t;
# elif __ARM_ARCH >= 6
int64_t t;
cpu = 0xFFFFFFFF;
asm volatile ( "mrrc p15, 1, %Q0, %R0, c14" : "=r" (t) );
return t;
# elif defined _MSC_VER || defined __CYGWIN__ # elif defined _MSC_VER || defined __CYGWIN__
const auto t = int64_t( __rdtscp( &cpu ) ); const auto t = int64_t( __rdtscp( &cpu ) );
return t; return t;
@ -95,14 +88,8 @@ public:
static tracy_force_inline int64_t GetTime() static tracy_force_inline int64_t GetTime()
{ {
#ifdef TRACY_HW_TIMER #ifdef TRACY_HW_TIMER
# if defined __aarch64__ # if __ARM_ARCH >= 6
int64_t t; return GetTimeImpl();
asm volatile ( "mrs %0, cntvct_el0" : "=r" (t) );
return t;
# elif __ARM_ARCH >= 6
int64_t t;
asm volatile ( "mrrc p15, 1, %Q0, %R0, c14" : "=r" (t) );
return t;
# elif defined _MSC_VER || defined __CYGWIN__ # elif defined _MSC_VER || defined __CYGWIN__
unsigned int dontcare; unsigned int dontcare;
const auto t = int64_t( __rdtscp( &dontcare ) ); const auto t = int64_t( __rdtscp( &dontcare ) );