/*Orion Lawlor's Simple x86 assembly Examples, olawlor@acm.org, 2003/09/01
Shows how to use the "rdtsc" instruction.
*/
#include <stdio.h>
double scale=1.0;

/* Use x86 assembly "rdtsc" instruction. */
double access_counter(void)
{
  unsigned long long int v;
  int *lo=0+(int *)&v;
  int *hi=1+(int *)&v;
  __asm__ __volatile__(
      "rdtsc; movl %%edx,%0; movl %%eax,%1"
      : /* output  */ "=m" (*hi), "=m" (*lo)
      : /* input */
      : /* trashes */ "%edx", "%eax"
  );
  return scale*v;
}

int main() {
  int i;
  const int n=1000000;
  double sum, smallest, largest;
  smallest=1.0e20;
  largest=-1.0e20;
  sum=0.0;
  for (i=0;i<n;i++) {
	double start=access_counter();
	double elapsed=access_counter()-start;
  	if (elapsed<smallest) smallest=elapsed;
  	if (elapsed>largest) largest=elapsed;
	sum+=elapsed;
  }
  
  printf("%.2f clocks (%.0f min, %.0f max)\n",
  	sum/n, smallest, largest);
}
/*<@>
<@> ******** Program output: ********
<@> 71.65 clocks (71 min, 58416 max)
<@> */
