[vox-tech] Easiest way to calculate date in 100 ns increments?

Bill Broadley bill at cse.ucdavis.edu
Thu Jun 24 02:59:17 PDT 2004


On Wed, Jun 23, 2004 at 03:28:41PM -0700, Rick Moen wrote:
> Quoting Mark K. Kim (lugod at cbreak.org):
> 
> > Having said that, `date` is a nice tool for converting from human readable
> > format to hour/minute/sec/nanosec if you're scripting, and the source is
> > freely available if you're using C!
> 
> Most likely, the results wouldn't be meaningful since the querent is
> looking for 100 ns resolution.  I believe that date uses gettimeofday,
> which is at best accurate to about two microseconds.  It'd be a

I'm pretty sure that on linux, er probably any machine with glibc,
gettimeofday is a pretty small wrapper around the cycle counter.  To
test this theory I wrote a test program and ran it on a 2.2 GHz cpu:
j=88 gtod diff=0.000001 getcycle diff=8
j=89 gtod diff=0.000000 getcycle diff=5
j=90 gtod diff=0.000000 getcycle diff=8
j=91 gtod diff=0.000000 getcycle diff=5
j=92 gtod diff=0.000000 getcycle diff=8
j=93 gtod diff=0.000001 getcycle diff=5

So in 5 trips through this loop the cycle counter went up
by 31 cycles @ 0.4545ns per cycle = 14.09 ns.  In that time
gtod incremented.  So it looks like 14ns or so accuracy
to me.  I'll attach my code.

> If you need 100 ns resolution, therefore, it's better to use something
> like Robert G. Brown's nanotimer utility, which reads and uses
> information from the on-board cycle counter accessible on pretty much
> all modern CPUs.  See:
> 
> http://www.beowulf.org/pipermail/beowulf/2004-January/009028.html

Or just use getcycle and divide by clockspeed.  

-- 
Bill Broadley
Computational Science and Engineering
UC Davis
-------------- next part --------------
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>

/* time_compare.c - version 0.1 - compares gettimeofday to getcycle */
/* written by Bill Broadley bill at cse.ucdavis.edu */

double gtod (void)
{
  struct timeval tv;
  gettimeofday(&tv, 0);
  return tv.tv_sec + 1e-6 * tv.tv_usec;
}

inline
unsigned long long
getcycle (void)
{
  unsigned long long tsc;
  __asm__ __volatile__ ("rdtsc" : "=A" (tsc));
  return ((unsigned long long) tsc);
}

int main()
{
	double g[100];
	unsigned long long r[100];
	int j;

	for (j=0;j<100;j++)
	{
		g[j]=gtod();
	}
	for (j=0;j<100;j++)
	{
		r[j]=getcycle();
	}
	
	for (j=1;j<100;j++)
	{
		printf ("j=%d gtod diff=%11.10f getcycle diff=%llu\n",j,g[j]-g[j-1],
		r[j]-r[j-1]);
	}
	return(0);
}	


More information about the vox-tech mailing list