Почему мой System.nanoTime () сломан?

Я и еще один разработчик моего времени недавно перешли с работающего на Core 2 Duo компьютера на новый Core 2 Quad 9505; оба работают под управлением Windows XP SP3 32-bit с JDK 1.6.0_18.

После этого пара наших автоматических модульных тестов для некоторого кода агрегации синхронизации / статистики / метрик быстро начала давать сбой из-за смешных значений, возвращаемых System.nanoTime ().

Тестовый код, который надежно демонстрирует это поведение на моей машине:

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

}

Типичный вывод:

millisTaken=5001
nanosTaken=2243785148

Запуск 100x дает нано результаты от 33% до 60% фактического времени сна; обычно около 40%.

Я понимаю недостатки точности таймеров в Windows, и прочитал связанные темы, такие какЯвляется ли System.nanoTime () одинаковым для всех потоков?Однако, насколько я понимаю, System.nanoTime () предназначен именно для той цели, которую мы используем: - измерение прошедшего времени; более точно, чем currentTimeMillis ().

Кто-нибудь знает, почему он дает такие безумные результаты? Скорее всего, это проблема аппаратной архитектуры (единственное, что изменилось - это процессор / материнская плата на этом компьютере)? Проблема с Windows HAL с моим текущим оборудованием? Проблема JDK? Должен ли я отказаться от nanoTime ()? Должен ли я где-то регистрировать ошибку или какие-либо предложения о том, как я мог бы продолжить расследование?

ОБНОВЛЕНИЕ 19/07 03:15 UTC: Попробовав тестовый пример finnw, приведенный ниже, я сделал еще один поиск в Google, наткнувшись на такие записи, какBUGID: 6440250, Это также напомнило мне о каком-то другом странном поведении, которое я заметил поздней пятницей, когда пинги возвращались отрицательными. Итак, я добавил/ usepmtimer на мой boot.ini и теперь все тесты ведут себя как положено., и мой пинг тоже нормальный.

Я немного смущен тем, почему это все еще было проблемой; из моего прочтения я подумал, что проблемы TSC и PMT были в основном решены в Windows XP SP3. Может ли это быть потому, что моя машина изначально была SP2 и была исправлена ​​на SP3, а не установлена ​​изначально как SP3? Теперь я также спрашиваю себя, стоит ли мне устанавливать патчи, как наMS KB896256, Может быть, мне стоит заняться этим с командой по сборке корпоративного рабочего стола?

Ответы на вопрос(4)

Ваш ответ на вопрос