getCurrentTicks() resolution

From the getCurrentTicks() docs:

Returns the current value of the performance counter. This number has no meaning on its own (ie. its units are undefined) but can be used in calls to getSecondsBetweenTicks() to measure absolute elapsed time. Note that the value returned by getCurrentTicks() is not affected by system (“wall”) clock time changes.

… ok. So it's not a timestamp?
What does "units are undefined" mean, can it vary across OSes/machines/Fabric versions? On a given machine/session, are the values returned by getCurrentTicks() linear with time? Are they at least sequential, ie can be used for sorting?

I tried the following:

dfgEntry {
  report(getSecondsBetweenTicks(0, 1));
  report(getSecondsBetweenTicks(0, 10));
  report(getSecondsBetweenTicks(0, 100));
  report(getSecondsBetweenTicks(0, 1000));
}

... got this output:

[FABRIC:MT] +1.0e-9
[FABRIC:MT] +1.0e-8
[FABRIC:MT] +1.0e-7
[FABRIC:MT] +1.0e-6

... looks to me like 1 tick == 1 ns :)

R&D Developer at Dwarf Animation Studio

Comments

  • pzionpzion Moderator, Fabric Employee Posts: 118 Fabric Employee

    It's not a timestamp, it's just measures clock cycles that have occurred since the CPU was turned on. It looks like on your platform 1 tick = 1 ns, but there's no guarantee that will be true on another platform or even on a different CPU.

    Peter Zion
    Fabric Engine

  • benblobenblo Posts: 29

    OK thanks. But it's still a constant unit for a given platform/CPU, right? The doc makes it sound like some black magic value that can only be mapped to getSecondsBetweenTicks()...

    R&D Developer at Dwarf Animation Studio

  • pzionpzion Moderator, Fabric Employee Posts: 118 Fabric Employee

    It's probably constant for fixed CPU and OS, yes. All that it is is the OS high resolution timer value. You can fine the implementation in the open-source FTL library we've written at http://github.com/fabric-engine/FTL, the details are:

    inline uint64_t GetCurrentTicks()
    {
    #if defined(FTL_OS_WINDOWS)
      LARGE_INTEGER counts;
      ::QueryPerformanceCounter( &counts );
      return uint64_t( counts.QuadPart );
    #elif defined(FTL_OS_LINUX)
      struct timespec tv;
      clock_gettime( CLOCK_MONOTONIC, &tv );
      return uint64_t(tv.tv_sec) * uint64_t(1000000000) + uint64_t(tv.tv_nsec);
    #elif defined(FTL_OS_DARWIN)
      return mach_absolute_time();
    #else
    # error "Unsupported OS"
    #endif
    }
    
    inline double GetSecondsForTicksDiff( uint64_t ticksDiff )
    {
    #if defined(FTL_OS_WINDOWS)
      static double secondsPerTick = 0.0;
      if ( !secondsPerTick )
      {
        LARGE_INTEGER ticksPerSecond;
        ::QueryPerformanceFrequency( &ticksPerSecond );
        secondsPerTick = 1.0 / double(ticksPerSecond.QuadPart);
      }
      return double(ticksDiff) * secondsPerTick;
    #elif defined(FTL_OS_LINUX)
      return double(ticksDiff) * 1e-9;
    #elif defined(FTL_OS_DARWIN)
      static mach_timebase_info_data_t sTimebaseInfo;
      if ( !sTimebaseInfo.denom )
        mach_timebase_info(&sTimebaseInfo);
      return double(ticksDiff) * double(sTimebaseInfo.numer) * 1e-9 / double(sTimebaseInfo.denom);
    #else
    # error "Unsupported OS"
    #endif
    }
    

    Peter Zion
    Fabric Engine

  • benblobenblo Posts: 29

    Ah perfect, thanks a lot Peter!

    R&D Developer at Dwarf Animation Studio

Sign In or Register to comment.