Subject: Re: High res timer on i386
To: None <netbsd-help@netbsd.org>
From: Wolfgang S. Rupprecht <wolfgang+gnus20030806T132832@wsrcc.com>
List: netbsd-help
Date: 08/06/2003 13:33:55
spence@panix.com (Michael D. Spence) writes:
> Windows has QueryPerformanceFrequency and QueryPerformanceCounter,
> which evidently do something with a high-resolution clock.
>
> Does NetBSD offer access to this device?
Modern x86 have a cpu clock cycle counter. If you are running with a
constant clock you can use the TSC counter. (This obviously doesn't
work if you have one of those goofy "speed step" portables that turn
the clock speed up and down at run-time).
-wolfgang
/* cc -O2 -g -Wall -Wmissing-prototypes -Wmissing-declarations -Wuninitialized tsc2.c -o tsc2 */
#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
typedef unsigned long long u64;
double timestamp(void);
inline u64 getTick64(void);
inline u64
getTick64(void)
{
u64 ticks;
asm volatile("rdtsc":"=A"(ticks));
return ticks;
}
double
timestamp(void)
{
double sec;
struct timeval ts;
gettimeofday(&ts, NULL);
sec = ts.tv_sec;
sec += ts.tv_usec * 1e-6;
return (sec);
}
int
main(void)
{
int i;
u64 start = 0,
end;
double fstart = 0.0,
fend,
ticspersec;
fstart = timestamp();
start = getTick64();
sleep(1);
fend = timestamp();
end = getTick64();
ticspersec = (end - start) / (fend - fstart);
for (i = 0; i < 10000000; i++) {
start = getTick64();
fstart = timestamp();
fend = timestamp();
end = getTick64();
if (fend < fstart) {
printf("retrograde: %1.20e -> %1.20e (%1.20e)\n",
fstart, fend, fend - fstart);
printf(" tsc: %llu -> %llu (%llu tics, %1.20e seconds)\n",
start, end, end - start, (end - start) / ticspersec);
printf("error ~= %1.20e\n",
fend - fstart - ((end - start) / ticspersec));
}
}
exit(0);
}
--
Wolfgang S. Rupprecht http://www.wsrcc.com/wolfgang/
(NOTE: The email address above is valid. Edit it at your own peril.)