Ver Mensaje Individual
  #3 (permalink)  
Antiguo 25/07/2006, 10:59
jferrero
Colaborador
 
Fecha de Ingreso: mayo-2006
Ubicación: Valladolid
Mensajes: 524
Antigüedad: 18 años
Puntos: 11
El asunto es muy complicado.

Primero tienes que ver tu máquina. Debe disponer de un reloj hardware que sea capaz de entregar el tiempo con esa precisión. Si no dispone de ningún circuito que lo haga, deberás instalarle una tarjeta medidora de tiempos o una con reloj incorporado. En la gran mayoría de los ordenadores (PC) actuales no vienen equipados con esa precisión. Me explico:

Según la normativa ISA, los ordenadores vienen equipados con un reloj en la placa base alimentado por una batería (una pila de tipo botón, normalmente). Cuando el sistema operativo interroga al reloj, este devuelve la hora con precisión de 1 segundo, pero el programa de control que lo maneja es capaz de ver el flanco de variación dentro de un segundo, por lo que se dice que ese reloj tiene precisión infinita, aunque luego, el sistema operativo, sólo se quede con 5 o 6 decimales.

Pero ahora viene lo malo: el sistema operativo, en un PC, tarda un MONTÓN en leer esa información. La interface es muy lenta. Sólo tienes que hacer la prueba en un linux e intentar ejecutar el programa hwclock.

Esa es la razón por la que en las grandes competiciones se usan tarjetas de adquisión de datos unidas a máquinas medidoras de tiempos externas (o tarjetas medidoras de tiempos).

Lo que nunca hay que hacer es fiarse de la precisión de un programa hecho por nosotros. Aunque lo hagamos muy bien, ese programa no corre solo en el ordenador, por lo que es continuamente interrumpido.

En Perl, la situación no es mucho mejor, ya que depende del sistema operativo. Desde que mandas arrancar el programa y este da las órdenes de qué tiempo es ahora, pasa una eternidad hasta obtener una respuesta.

Se dispone del módulo Time::Hires en CPAN, que es una interface con la función del sistema gettimeofday, que devuelve dos valores: el número de segundos y el número de microsegundos desde el epoch -según el horario del sistema-. Tendrás que leerte su documentación, que trae detalles curiosos...

Naturalmente, en Windows, ni se te ocurra hacer de estas cosas... el influjo del resto de los programas falsea todos los resultados. La mejor opción es usar un RTLinux (Real Time Linux) o una máquina específica o un PC de gama alta (alta velocidad de bus interno) equipado con un tarjeta de adquisión/reloj.

Curiosamente, los ordenadores de los años 80 estaban mejor equipados en cuanto a hardware para ofrecer este tipo de soluciones. Los ejemplo más claros eran los ordenadores Atari, los Amiga y los MSX. Con los Atari conseguí hacer un reloj con precisión de centésimas (concretamente, su reloj tenía un periodo de 50ms), pero los mejores que yo ví fueron los MSX que, con un sencillo programa en Basic sacaban la hora con precisión de 1ms.

Al final, todo depende de lo exacto que quieras obtener el resultado. Se puede hacer un programa muy pequeño con el módulo Time::Hires que diga el tiempo que ha pasado entre dos pulsaciones a la tecla return. Si es para medir cuánto tiempo tarda en dar una vuelta un corredor de atletismo en las fiestas del pueblo, pues vale. Para saber cuánto le lleva de ventaja Fernando Alonso a Shumacher, no. Mientras pulsas el botón de return y Perl se entera y saca el tiempo actual, Fernando se ha desplazado con su coche 4 metros más: 300Kmh/3.600.000ms=0,083m/ms. Si la operación tarda 50ms, Fernando se desplaza 4,15 metros.