Почему мой 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, Может быть, мне стоит заняться этим с командой по сборке корпоративного рабочего стола?