Measuring clock offset results

Thangalin <[email protected]>
Newsgroups gmane.comp.time.chrony.user
Message-ID <CAANrE7rTQL0Eg088ZbJEo64ZyY0i=Vgythex-CQ55Poro_TuJA@mail.gmail.com>
Hi all,

Thank you for suggesting we use /sys/class/pps/pps1/assert to measure the
clock. (Source code below.) Here's a comparison of the results between
chrony and ntpd over 24 hours:

https://ibb.co/album/5YxH2m

Chrony clearly improves the offsets to sub-20 microseconds much of the
time. We're seeing some spikes in the timing, though, that exceed ntpd.*
The chrony configuration file is the same as in the other thread (
https://www.mail-archive.com/[email protected]/msg03281.html
).

Other processes may be affected by changing the CPU, so we haven't switched
to a constant frequency nor disabled the power saving states (e.g.
idle=poll).

Setting sched_priority to 1 yields a modest improvement over an hour:

https://ibb.co/album/1Z824p

Are there any other ways we could help chronyd stay below 20 microseconds
(e.g., optimized build) that may have been overlooked (besides using GPIO)?

Many thanks!

*ntpd had one 1500+ us outlier, which we removed from the graphs.

P.S.
Code improvement suggestions welcome:

// SOF
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>
#include <time.h>

#define PPS_DEVICE "/sys/class/pps/pps1/assert"

static void diff_timespec(
  const struct timespec *time1,
  const struct timespec *time0,
  struct timespec* diff ) {
  diff->tv_sec = time1->tv_sec - time0->tv_sec;
  diff->tv_nsec = time1->tv_nsec - time0->tv_nsec;

  if( diff->tv_nsec < 0 ) {
    // nsec/sec
    diff->tv_nsec += 1000000000;
    diff->tv_sec--;
  }
}

int main( int argc, char** argv ) {
  struct timespec curr_pps_time = {0};
  struct timespec prev_pps_time = {0};
  int curr_assert = 0;
  int prev_assert = -1;
  struct timespec diff = {0};
  struct timespec drift = {0};
  char pps_buff[64] = {'\0'};

  printf( "seconds,nanoSeconds\n" );

  FILE* pps_fd = fopen( PPS_DEVICE, "r" );

  while( 1 ) {
    fread( pps_buff,1, 63, pps_fd );

    sscanf( pps_buff, "%ld.%ld#%d",
      &curr_pps_time.tv_sec,
      &curr_pps_time.tv_nsec,
      &curr_assert );

    if( prev_assert == -1 ) {
      prev_assert = curr_assert;
      prev_pps_time.tv_sec = curr_pps_time.tv_sec;
      prev_pps_time.tv_nsec = curr_pps_time.tv_nsec;
    }

    if( ( curr_assert - prev_assert ) == 1 ) {
      struct timespec one_second = {.tv_sec = 1, .tv_nsec = 0};

      diff_timespec( &curr_pps_time, &prev_pps_time, &diff );
      diff.tv_sec >= 1
        ? diff_timespec( &diff, &one_second, &drift )
        : diff_timespec( &one_second, &diff, &drift );

      printf( "%ld,%ld\n", drift.tv_sec, drift.tv_nsec );
      fflush( stdout );

      prev_assert = curr_assert;
      prev_pps_time.tv_sec = curr_pps_time.tv_sec;
      prev_pps_time.tv_nsec = curr_pps_time.tv_nsec;
    }

    fseek( pps_fd,0,SEEK_SET );
    usleep( 250000 );
  }

  fclose( pps_fd );
  return 0;
}
// EOF

Graphs were generated using R:

# SOF

plotOffsets <- function( filename ) {

  csv.data <- read.table( filename, sep=",", header=T, na.strings="",
stringsAsFactors=F );



  csv.data$nanoSeconds <- csv.data$nanoSeconds / 1000;



  plot(x=1:length(csv.data$nanoSeconds), csv.data$nanoSeconds,
xlab="index", ylab="offset (us)", type="l");

}

# EOF
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.