Subject: Re: [linux-audio-dev] best method for timing
From: Paul Davis (pbd_AT_Op.Net)
Date: Wed Apr 17 2002 - 02:14:27 EEST
>In Windows I use the rdtsc assembler instruction. It returns a 64 bit
>integer (in EAX:EDX I think) which represent the amount of processors cycles
>that have passed from the last reset. Computing the difference between two
>values and taking into account the freq of the CPU (you have to figure it
>out somehow),
reading /proc/cpuinfo is the best way, but this code will also work:
----------------------------------------------------------------------
/*
* This was originally written by Mark Hahn. Obtained from
* http://brain.mcmaster.ca/~hahn/realfeel.c
*/
double second() {
struct timeval tv;
gettimeofday(&tv,0);
return tv.tv_sec + 1e-6 * tv.tv_usec;
}
typedef unsigned long long u64;
void selectsleep(unsigned us) {
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = us;
select(0,0,0,0,&tv);
}
double secondsPerTick, ticksPerSecond;
void calibrate()
{
double sumx = 0;
double sumy = 0;
double sumxx = 0;
double sumxy = 0;
double slope;
// least squares linear regression of ticks onto real time
// as returned by gettimeofday.
const unsigned n = 30;
unsigned i;
for (i=0; i<n; i++) {
double breal,real,ticks;
u64 bticks;
breal = second();
bticks = rdtsc();
selectsleep((unsigned)(10000 + drand48() * 200000));
ticks = get_cycles - bticks;
real = second() - breal;
sumx += real;
sumxx += real * real;
sumxy += real * ticks;
sumy += ticks;
}
slope = ((sumxy - (sumx*sumy) / n) /
(sumxx - (sumx*sumx) / n));
ticksPerSecond = slope;
secondsPerTick = 1.0 / slope;
printf("%3.3f MHz\n",ticksPerSecond*1e-6);
}
----------------------------------------------------------------------
> you get a very accurate timer.
timer yes, but periodic wake up source, no. doing sequencing on a
general purpose OS requires that your sequencer thread sleeps from
time to time, and the cycle counter by itself can't help there.
>Maybe someone can convert this code to Linux:
Sure (thanks to Kai for pointing out <asm/timex.h>
----------------------------------------------------------------------
#include <asm/timex.h>
...
cycles_t cycles = get_cycles();
...
----------------------------------------------------------------------
this will work on at least x86, ppc and alpha.
--p
This archive was generated by hypermail 2b28 : Wed Apr 17 2002 - 02:00:01 EEST