View Single Post
Old 04-10-2004, 17:19   #19
ilsensine
Senior Member
 
L'Avatar di ilsensine
 
Iscritto dal: Apr 2000
Cittā: Roma
Messaggi: 15625
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.
ilsensine č offline   Rispondi citando il messaggio o parte di esso