2009-10-02 10 views

Respuesta

9

Los sistemas operativos de escritorio de Windows realmente no son precisos por debajo de unos 40 ms. El sistema operativo simplemente no es en tiempo real y, por lo tanto, presenta una trepidación significativa no determinista. Lo que eso significa es que, si bien puede informar valores de hasta milisegundos o incluso menores, no se puede contar realmente con que esos valores sean realmente significativos. Así que aunque el intervalo del Temporizador se establece en algún valor de menos de milisegundos, no puede confiar en los tiempos entre la configuración y la activación para que realmente sea lo que dijo que quería.

Agregue a este hecho que todo el marco en el que se ejecuta no es determinista (el GC podría suspenderlo y hacer la recolección del tiempo cuando el temporizador debería disparar) y termina con muchas cargas de riesgo probando hacer cualquier cosa que sea crítica en el tiempo.

+0

No es particularmente crítico; Estoy escribiendo un "procesador virtual" para un juego de simulación de robots que usa un temporizador para ejecutar instrucciones a una velocidad específica y me pregunto qué tan alto puedo configurarlo. – RCIX

+1

No trataría de ir más de 1ms. El programador del sistema operativo no hará nada más frecuente que el de su aplicación de todos modos. – ctacke

+0

De acuerdo, gracias por la información! – RCIX

2

System.Timers.Timer es extraño. Está utilizando un doble como intervalo, pero de hecho llama a Math.Ceiling y arroja el resultado como un int para usar con un System.Threading.Timer subyacente. Su precisión teórica es de 1 ms y no puede especificar un intervalo que exceda los 2.147.483.647 ms. Dada esta información, realmente no sé por qué se usa un doble como parámetro de intervalo.

2

Hace un par de años encontré que tenía una precisión de aproximadamente 16 ms ... pero desafortunadamente no recuerdo los detalles.

+4

Eso será 15.625ms == 64Hz, la frecuencia del reloj del sistema. –

1

Puede encontrarlo fácilmente realizando un ciclo que muestrea constantemente la duración del tiempo resultante y compruebe qué granularidad sigue.

0

He comparado System.Timers.Timer y System.Threading.Timer - ambos dan errores sistemáticos alrededor de 8..16 ms, especialmente en intervalos pequeños (1000..6000 ms). Cada llamada subsiguiente de la rutina del temporizador se produjo con un intervalo mayor desde la primera llamada. Por ejemplo, un temporizador con un intervalo de 2000 ms se dispara en 2000, 4012, 6024, 8036, 10048 milisegundos, etc. (las marcas de tiempo obtenidas de Environment.TickCount y Stopwatch.ElapsedTicks, ambos dan los mismos resultados).

0

La resolución del temporizador baja al régimen de 1 ms sin mucho esfuerzo de implementación. Acabo de describir el motivo de la precisión double en this answer. Al configurar el sistema a para que se ejecute a 1024 interrupciones por segundo (utilizando la API del temporizador multimedia), el tiempo entre las interrupciones es de 0,9765625 ms. La resolución estándar para cuestiones de tiempo es 100ns. Esos valores se almacenan como enteros. El valor 0.9765625 no puede almacenarse sin perder precisión en un número entero con una resolución de 100 ns. El último dígito (5) representa 500 ps. Por lo tanto, la resolución debe ser tres órdenes de magnitud mayor. Almacenar estos valores de tiempo en enteros con una resolución de 100 ps no es posible ya que un entero de 8 bytes a una resolución de 100 ps se envolvería después de unos 21350 días o aproximadamente 58 años. Este lapso de tiempo es demasiado corto para ser aceptado por cualquier persona (¡recuerde el escenario del Y2K!).

Consulte la respuesta vinculada para obtener más información sobre los detalles.

Cuestiones relacionadas