Warum ist meine System.nanoTime () kaputt?

Ich selbst und ein anderer Entwickler meiner Zeit sind kürzlich von einem Core 2 Duo-Rechner bei der Arbeit auf einen neuen Core 2 Quad 9505 umgezogen. beide unter Windows XP SP3 32-Bit mit JDK 1.6.0_18.

Upon dies tuend, begannen einige unserer automatisierten Komponententests für einige Timing- / Statistik- / Metrik-Aggregationscodes prompt fehlzuschlagen, da scheinbar lächerliche Werte von System.nanoTime () zurückgegeben wurden.

Testcode, der dieses Verhalten zuverlässig auf meinem Computer anzeigt, lautet:

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));
  }

}

Typische Ausgabe:

millisTaken=5001
nanosTaken=2243785148

Running it 100x ergibt Nanoergebnisse zwischen 33% und 60% der tatsächlichen Schlafzeit; in der Regel um die 40%.

Ich verstehe die Schwachstellen in der Genauigkeit von Timern in Windows und habe verwandte Threads wie @ geleseIst System.nanoTime () über alle Threads konsistent?, aber ich verstehe, dass System.nanoTime () genau für den Zweck vorgesehen ist, den wir verwenden: - Messung der verstrichenen Zeit; genauer als currentTimeMillis ().

Weiß jemand, warum es so verrückte Ergebnisse zurückgibt? Handelt es sich wahrscheinlich um ein Hardwarearchitekturproblem (das einzige, was sich geändert hat, ist die CPU / das Motherboard auf diesem Computer)? Ein Problem mit der Windows HAL mit meiner aktuellen Hardware? Ein JDK-Problem? Soll ich nanoTime () verlassen? Sollte ich irgendwo einen Fehler melden oder Vorschläge machen, wie ich weitere Nachforschungen anstellen könnte?

UPDATE 19/07 03:15 UTC: Nachdem ich den Testfall von finnw unten ausprobiert hatte, habe ich noch ein bisschen gegoogelt und bin auf Einträge wie @ gestoßebugid: 6440250. Es erinnerte mich auch an ein anderes merkwürdiges Verhalten, das ich am späten Freitag bemerkte, als die Pings negativ zurückkamen. Also habe ich @ hinzugefü / usepmtimer zu meiner boot.ini und jetzt verhalten sich alle Tests wie erwartet und meine Pings sind auch normal.

Ich bin ein bisschen verwirrt darüber, warum dies immer noch ein Problem war. Aus meiner Lektüre ging hervor, dass TSC- und PMT-Probleme in Windows XP SP3 weitgehend behoben wurden. Könnte es daran liegen, dass mein Computer ursprünglich SP2 war und auf SP3 gepatcht und nicht ursprünglich als SP3 installiert wurde? Ich frage mich jetzt auch, ob ich Patches wie den unter @ installieren solMS KB896256. Vielleicht sollte ich das mit dem Desktop-Build-Team des Unternehmens besprechen?

Antworten auf die Frage(8)

Ihre Antwort auf die Frage