Самостоятельно и еще один разработчик моего времени недавно переехал с машины Core 2 Duo на работу на новый Core 2 Quad 9505; оба работают под управлением Windows XP SP3 32-бит с JDK 1.6.0_18.Почему мой System.nanoTime() сломан?
После этого несколько наших автоматических модульных тестов для некоторого кода агрегации времени/статистики/показателей быстро начали сбой, из-за того, что кажется смешными значениями, возвращающимися из 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 и читаю связанные темы, такие как Is System.nanoTime() consistent across threads?, однако я понимаю, что System.nanoTime() предназначен именно для того, чтобы мы его использовали: - измерение прошедшего времени; точнее, чем currentTimeMillis().
Кто-нибудь знает, почему он возвращает такие сумасшедшие результаты? Возможно, это проблема аппаратной архитектуры (единственная важная вещь, которая изменилась, - это процессор/материнская плата на этой машине)? Проблема с Windows HAL с моим текущим оборудованием? Проблема JDK? Должен ли я отказаться от nanoTime()? Должен ли я где-нибудь регистрировать ошибку или какие-либо предложения о том, как я могу продолжить исследование?
UPDATE 19/07 03:15 UTC: После проверки тестового примера в Finnw ниже я сделал еще несколько поисковых запросов, попадающих в такие записи, как bugid:6440250. Это также напомнило мне о каком-то другом странном поведении, которое я заметил в конце пятницы, когда пинги возвращались отрицательно. Поэтому я добавил /usepmtimer в мой boot.ini, и теперь все тесты ведут себя так, как ожидалось., И мои пинги тоже нормальные.
Я немного смущен, почему это все еще проблема; из моего чтения я думал, что проблемы TSC и PMT были в основном решены в Windows XP SP3. Может быть, из-за того, что моя машина была первоначально SP2, и была исправлена до SP3, а не изначально установлена как SP3? Теперь я также задаюсь вопросом, следует ли устанавливать патчи, например, на MS KB896256. Может быть, я должен взять это с командой разработчиков настольных компьютеров?
Вы получили совершенно новую машину или обновили свой текущий компьютер, сохраняя старую установку Windows? –
Полностью новая машина; перестроен по корпоративной стандартной сборке. – Chad
работает отлично для меня под Windows 7 64-разрядный последний JDK 6. – TofuBeer