¿Por qué mi System.nanoTime () está roto?

Yo y otro desarrollador de mi tiempo recientemente nos mudamos de una máquina Core 2 Duo en el trabajo a un nuevo Core 2 Quad 9505; ambos ejecutan Windows XP SP3 de 32 bits con JDK 1.6.0_18.

Al hacerlo, un par de nuestras pruebas unitarias automatizadas para algunos códigos de agregación de tiempo / estadísticas / métricas comenzaron a fallar rápidamente, debido a lo que parecen ser valores ridículos que regresan de System.nanoTime ().

El código de prueba que muestra este comportamiento, de manera confiable, en mi máquina es:

import static org.junit.Assert.assertThat;

import org.hamcrest.Matchers;
import org.junit.Test;

public class NanoTest {

  @Test
  public void testNanoTime() throws InterruptedException {
    final long sleepMillis = 5000;

    long nanosBefore = System.nanoTime();
    long millisBefore = System.currentTimeMillis();

    Thread.sleep(sleepMillis);

    long nanosTaken = System.nanoTime() - nanosBefore;
    long millisTaken = System.currentTimeMillis() - millisBefore;

    System.out.println("nanosTaken="+nanosTaken);
    System.out.println("millisTaken="+millisTaken);

    // Check it slept within 10% of requested time
    assertThat((double)millisTaken, Matchers.closeTo(sleepMillis, sleepMillis * 0.1));
    assertThat((double)nanosTaken, Matchers.closeTo(sleepMillis * 1000000, sleepMillis * 1000000 * 0.1));
  }

}

Salida típica:

millisTaken=5001
nanosTaken=2243785148

Ejecutarlo 100x produce resultados nano entre el 33% y el 60% del tiempo de sueño real; aunque generalmente alrededor del 40%.

Entiendo las debilidades en la precisión de los temporizadores en Windows, y he leído hilos relacionados como¿System.nanoTime () es coherente en todos los subprocesos?, sin embargo, entiendo que System.nanoTime () está destinado exactamente para el propósito que lo estamos usando: - medir el tiempo transcurrido; con mayor precisión que currentTimeMillis ().

¿Alguien sabe por qué está devolviendo resultados tan locos? ¿Es probable que sea un problema de arquitectura de hardware (lo único que ha cambiado es la CPU / placa base de esta máquina)? ¿Un problema con el HAL de Windows con mi hardware actual? ¿Un problema de JDK? ¿Debo abandonar nanoTime ()? ¿Debo registrar un error en alguna parte o alguna sugerencia sobre cómo podría investigar más?

ACTUALIZACIÓN 19/07 03:15 UTC: Después de probar el caso de prueba de finnw a continuación, busqué más en Google, encontré entradas comobugid: 6440250. También me recordó algún otro comportamiento extraño que noté el viernes por la noche donde los pings estaban volviendo negativos. Entonces agregué/ usepmtimer a mi boot.ini y ahora todas las pruebas se comportan como se esperaba, y mis pings también son normales.

Sin embargo, estoy un poco confundido acerca de por qué esto todavía era un problema; De mi lectura, pensé que los problemas de TSC vs PMT se resolvieron en gran medida en Windows XP SP3. ¿Podría ser porque mi máquina era originalmente SP2 y estaba parcheada a SP3 en lugar de instalarse originalmente como SP3? Ahora también me pregunto si debería instalar parches como el deMS KB896256. ¿Tal vez debería abordar esto con el equipo de compilación de escritorio corporativo?

Respuestas a la pregunta(4)

Su respuesta a la pregunta