Questo programma imposta un intervallo del timer (settato dalla macro DELTA -- deve essere <= 8192), e calcola la media e dev. standard di quanto si discosta dall'istante temporale atteso. Se lo esegui con i privilegi di root sul kernel 2.6, otterrai i risultati che ho citato. Anche con il kernel 2.4 puoi ottenere buone prestazioni:
Codice:
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/poll.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <linux/rtc.h>
#include <math.h>
#include <sched.h>
#include <string.h>
static unsigned int __us(void) {
struct timeval tv;
gettimeofday(&tv, NULL);
return tv.tv_usec+tv.tv_sec*1000000;
}
static void __attribute__((__noreturn__)) fail(const char *fnc) {
perror(fnc);
exit(-1);
}
#define RATE 64
#define DELTAS 1024
int main(void) {
int fd;
double sum = 0.0;
double var = 0.0;
double delta;
double deltas[DELTAS] = { 0.0, };
int dpos = 0;
const double r = 1000000.0/RATE;
unsigned int items = 0;
struct pollfd pfd;
unsigned int t1;
unsigned int t2;
int rep;
struct sched_param p;
p.sched_priority = 10;
if(sched_setscheduler(getpid(), SCHED_FIFO, &p))
perror("sched_setscheduler");
if(mlockall(MCL_CURRENT|MCL_FUTURE))
perror("mlockall");
fd = open("/dev/rtc", O_RDONLY);
if(fd<0) fail("open");
if(ioctl(fd, RTC_IRQP_SET, RATE)<0)
fail("ioctl(RTC_IRQP_SET)");
pfd.fd = fd;
pfd.events = POLLIN;
for(rep=0; rep<10; ++rep) {
ioctl(fd, RTC_PIE_ON);
poll(&pfd, 1, -1);
ioctl(fd, RTC_PIE_OFF);
}
t2 = __us();
while(1) {
t1 = t2;
ioctl(fd, RTC_PIE_ON);
poll(&pfd, 1, -1);
t2 = __us();
ioctl(fd, RTC_PIE_OFF);
delta = fabs(r-(double)(t2-t1));
sum += delta - deltas[dpos];
var += delta*delta - deltas[dpos]*deltas[dpos];
deltas[dpos] = delta;
items<DELTAS && ++items;
++dpos>=DELTAS && (dpos = 0);
!--rep && (
fprintf(stderr, "avg=%0.2f us stddev=%0.3f us\n",
sum/items, items>1 ? sqrt(var)/(items-1) : sqrt(-1.0)),
(rep = 10)
);
}
}
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al
andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12
Ultima modifica di ilsensine : 04-10-2004 alle 17:23.
|