2010-06-29 20 views

Respuesta

7

Windows no quiere perder la electricidad mediante la actualización del reloj del sistema 1000 veces por segundo, por lo que el valor predeterminado es actualizar solamente se 60-100 veces por segundo. Si configura el temporizador multimedia en 1 ms, puede obtener una resolución de 1 ms del reloj, pero eso no es recomendable.

Para obtener más información sobre el ahorro de electricidad, lo que sucede cuando la CPU está inactiva durante un período de tiempo es que puede pasar a un estado de muy baja potencia. Cada vez que se interrumpe (por ejemplo, para aumentar los tics del reloj) tiene que dejar su estado de muy baja potencia y utilizar mucha electricidad para alimentar toda la CPU para dar servicio a esa interrupción. En otras palabras, la potencia adicional no está en aumentar los tics del reloj, sino en mantener despierta a la CPU para hacerlo.

Como mi computadora portátil usa 10W en ralentí cuando la frecuencia del reloj es 60Hz y 11W cuando es 1000Hz, y tengo 300 minutos de duración de la batería, ¡ese reloj más lento me da casi 30 minutos adicionales de duración de la batería!

+0

¿Estás hablando de las interrupciones del kernel? http://lwn.net/Articles/145973/ – Nitrodist

+0

Nitrodist: Sí, esa es una explicación del mismo problema. – Gabe

+0

Habla de la marca del kernel, una marca del kernel es una 'interrupción del temporizador 'del hardware programado (CPU). Sin embargo, Windows está lejos de ser bueno en la eficiencia de la electricidad (50% menos eficiente que Android, y 20% menos que Mac OS), pero no es razón para empeorar la situación. Los ticks del kernel se utilizan para invocar devoluciones de llamada de temporizadores caducados (o fusionados), volver a actualizar la programación de subprocesos/procesos e incrementar el conteo de ticks del sistema operativo mundial. –

6

Pruebe System.Diagnostics.Stopwatch para sincronizar en alta resolución.

Si el hardware instalado y sistema operativo admiten un contador de rendimiento de alta resolución, entonces la clase Cronómetro usos que contador para medir el tiempo transcurrido. De lo contrario, la clase Cronómetro usa el temporizador del sistema para medir el tiempo transcurrido de .

Pruebe el nativo DateTime.Ticks para precisión de tiempo del sistema de hasta cien nanosegundos; 1 milisegundo = 10000 tics.

while (true) 
{ 
    System.Threading.Thread.Sleep(1); 

    Console.WriteLine("{0} {1}", 
     System.DateTime.Now.Ticks, 
     System.DateTime.Now.ToString("ss:fff")); 
} 

PS > .\test.exe 
    634134152924322129 52:432 
    634134152924332129 52:433 
    634134152924342130 52:434 
    634134152924352130 52:435 
    634134152924362131 52:436 
    634134152924372131 52:437 
    634134152924382132 52:438 
    634134152924392133 52:439 
    634134152924402133 52:440 
    634134152924412134 52:441 
    634134152924422134 52:442 
    634134152924432135 52:443 
+3

Se preguntó por la hora del sistema. El cronómetro solo da un tiempo transcurrido. – Gabe

+3

Llamar 'DateTime.Ticks' no es más exacto que' DateTime.Millisecond'. Internamente, 'DateTime.Millisecond' llama a' DateTime.Ticks' –

+0

Derecha.Solo estaba señalando que de acuerdo con MSDN y esta prueba aproximada que es preciso, al menos, la resolución de milisegundos que está pidiendo el interrogador; de ahí el lado a lado Console.Output de DateTime como una cadena junto con Ticks. – xcud

8

Usted podría utilizar this DateTimePrecise class para obtener un tiempo de alta precisión en .NET

ACTUALIZACIÓN
El enlace CodeProject ya no está funcionando. He sacado el código from archive.org y lo he incluido aquí para referencia futura. Este código se incluye aquí "tal cual", exactamente como se incluyó en la página de CodeProject.

DateTimePrecise es tan fácil de usar como DateTime.Now, excepto que DateTimePrecise.Now es un método de instancia en lugar de un método estático, por lo que tiene para crear instancias de una primera DateTimePrecise.

using System.Diagnostics; 

/// DateTimePrecise provides a way to get a DateTime that exhibits the 
/// relative precision of 
/// System.Diagnostics.Stopwatch, and the absolute accuracy of DateTime.Now. 
public class DateTimePrecise 
{ 
    /// Creates a new instance of DateTimePrecise. 
    /// A large value of synchronizePeriodSeconds may cause arithmetic overthrow 
    /// exceptions to be thrown. A small value may cause the time to be unstable. 
    /// A good value is 10. 
    /// synchronizePeriodSeconds = The number of seconds after which the 
    /// DateTimePrecise will synchronize itself with the system clock. 
    public DateTimePrecise(long synchronizePeriodSeconds) 
    { 
     Stopwatch = Stopwatch.StartNew(); 
     this.Stopwatch.Start(); 

     DateTime t = DateTime.UtcNow; 
     _immutable = new DateTimePreciseSafeImmutable(t, t, Stopwatch.ElapsedTicks, 
      Stopwatch.Frequency); 

     _synchronizePeriodSeconds = synchronizePeriodSeconds; 
     _synchronizePeriodStopwatchTicks = synchronizePeriodSeconds * 
      Stopwatch.Frequency; 
     _synchronizePeriodClockTicks = synchronizePeriodSeconds * 
      _clockTickFrequency; 
    } 

    /// Returns the current date and time, just like DateTime.UtcNow. 
    public DateTime UtcNow 
    { 
     get 
     { 
      long s = this.Stopwatch.ElapsedTicks; 
      DateTimePreciseSafeImmutable immutable = _immutable; 

      if (s < immutable._s_observed + _synchronizePeriodStopwatchTicks) 
      { 
       return immutable._t_base.AddTicks(((
        s - immutable._s_observed) * _clockTickFrequency)/(
        immutable._stopWatchFrequency)); 
      } 
      else 
      { 
       DateTime t = DateTime.UtcNow; 

       DateTime t_base_new = immutable._t_base.AddTicks(((
        s - immutable._s_observed) * _clockTickFrequency)/(
        immutable._stopWatchFrequency)); 

       _immutable = new DateTimePreciseSafeImmutable(
        t, 
        t_base_new, 
        s, 
        ((s - immutable._s_observed) * _clockTickFrequency * 2) 
        /
        (t.Ticks - immutable._t_observed.Ticks + t.Ticks + 
         t.Ticks - t_base_new.Ticks - immutable._t_observed.Ticks) 
       ); 

       return t_base_new; 
      } 
     } 
    } 

    /// Returns the current date and time, just like DateTime.Now. 
    public DateTime Now 
    { 
     get 
     { 
      return this.UtcNow.ToLocalTime(); 
     } 
    } 

    /// The internal System.Diagnostics.Stopwatch used by this instance. 
    public Stopwatch Stopwatch; 

    private long _synchronizePeriodStopwatchTicks; 
    private long _synchronizePeriodSeconds; 
    private long _synchronizePeriodClockTicks; 
    private const long _clockTickFrequency = 10000000; 
    private DateTimePreciseSafeImmutable _immutable; 
} 

internal sealed class DateTimePreciseSafeImmutable 
{ 
    internal DateTimePreciseSafeImmutable(DateTime t_observed, DateTime t_base, 
     long s_observed, long stopWatchFrequency) 
    { 
     _t_observed = t_observed; 
     _t_base = t_base; 
     _s_observed = s_observed; 
     _stopWatchFrequency = stopWatchFrequency; 
    } 
    internal readonly DateTime _t_observed; 
    internal readonly DateTime _t_base; 
    internal readonly long _s_observed; 
    internal readonly long _stopWatchFrequency; 
} 
+0

¿Tiene la clase? El enlace ya no funciona. Gracias –

+0

@ Răzvan He resucitado el código de archive.org y lo he agregado a mi respuesta. Gracias por señalar que era un enlace muerto. –

+2

+1 para la resurrección –

Cuestiones relacionadas