Re: [linux-audio-dev] best method for timing

New Message Reply About this list Date view Thread view Subject view Author view Other groups

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


New Message Reply About this list Date view Thread view Subject view Author view Other groups

This archive was generated by hypermail 2b28 : Wed Apr 17 2002 - 02:00:01 EEST