Какое худшее разрешение я могу разумно ожидать от System.nanoTime?

Я пишу программное обеспечение, которое требует временных меток с разрешением в микросекунду или лучше.

Я планирую использовать System.currentTimeMillis в сочетании с System.nanoTime вроде как это, хотя это всего лишь примерный эскиз кода:

private static final long absoluteTime = (System.currentTimeMillis() * 1000 * 1000);
private static final long relativeTime = System.nanoTime();

public long getTime()
{
    final long delta = System.nanoTime() - relativeTime;
    if (delta < 0) throw new IllegalStateException("time delta is negative");
    return absoluteTime  + delta;
}

В документации для nanoTime указано:

Этот метод обеспечивает наносекундную точность, но не обязательно наносекундное разрешение (то есть, как часто изменяется значение) - нет предоставляются гарантии, за исключением того, что разрешение не менее < <24 > .

поэтому он не дал нам гарантии разрешения лучше, чем миллисекунды.

Подойдя немного глубже, под капотом nanoTime (который, как предсказуемо, является нативным методом):

  • В Windows используется QueryPerformanceCounter API, который promises a разрешение менее одной микросекунды, что отлично.

  • Linux использует clock_gettime с флагом, чтобы гарантировать, что это значение монотонно, но не делает promises о разрешении.

  • Solaris похожа на Linux

  • Источник не упоминает, как OSX или ОС на базе Unix справляются с этим.

(источник)

Я видел пару смутных намеков на то, что "обычно" будет иметь разрешение на микросекунду, например этот ответ по другому вопросу:

В большинстве систем три наименее значимые цифры всегда будут нуль. Это фактически дает точность в микросекундах, но сообщает об этом на фиксированный уровень точности наносекунды.

но нет источника, а слово "обычно" очень субъективно.

Вопрос: При каких обстоятельствах nanoTime возвращает значение, разрешение которого хуже микросекунд? Например, возможно, основная версия ОС не поддерживает его, или требуется конкретная аппаратная функция, которая может отсутствовать. Пожалуйста, постарайтесь предоставить источники, если сможете.


Я использую Java 1.6, но есть небольшая возможность, которую я мог бы обновить, если бы были существенные преимущества в отношении этой проблемы.

Ответ 1

Вопрос: В каких обстоятельствах nanoTime может вернуть значение, разрешение которого хуже, чем микросекунды? Какие операционные системы, аппаратные средства, JVM и т.д., Которые обычно используются, могут повлиять на это? Пожалуйста, постарайтесь предоставить источники, если сможете.

Просить исчерпывающий список всех возможных обстоятельств, при которых это ограничение будет нарушено, кажется немного, никто не знает, в каких средах будет работать ваше программное обеспечение. Но чтобы доказать, что это может произойти, см. Этот блог-пост от aleksey shipilev, где он описывает случай, когда нанотима становится менее точной (с точки зрения собственной задержка), чем микросекунда на машинах Windows, из-за конкуренции.

Другим случаем было бы программное обеспечение, работающее под виртуальной машиной, которое эмулирует аппаратные часы очень грубым образом.

Спецификация оставлена ​​преднамеренно неопределенной именно из-за поведения платформы и аппаратного обеспечения.

Вы можете "разумно ожидать" микросекундной точности, как только убедитесь, что аппаратное обеспечение и операционная система, которые вы используете, обеспечивают то, что вам нужно, и что виртуальные машины проходят через необходимые функции.