Какова цель JMH @Fork?

Если каждая вилка IIUC создает отдельную виртуальную машину по той причине, что каждый экземпляр виртуальной машины может работать с небольшими различиями в инструкциях JIT?

Мне также любопытно, что делает атрибут времени в приведенных ниже аннотациях:

@Warmup(iterations = 10, time = 500, timeUnit = TimeUnit.MILLISECONDS)
@Measurement(iterations = 10, time = 500, timeUnit = TimeUnit.MILLISECONDS)

Тиа, Оле


person Ole    schedule 27.01.2016    source источник
comment
Я думаю, что это отвечает на ваш вопрос: stackoverflow.com /вопросы/25572778/   -  person Tunaki    schedule 27.01.2016
comment
Итак, IIUC, каждая вилка работает на отдельной виртуальной машине. Мы делаем это, потому что для каждой запущенной виртуальной машины может быть небольшая разница, которая приведет к разному времени выполнения, следовательно, мы можем учесть это при расчете дисперсии?   -  person Ole    schedule 27.01.2016
comment
Да, между каждым запуском могут быть различия в поведении JIT, поэтому разветвление позволяет это учитывать. При выполнении тестов я видел очень странные случаи, когда один запуск имел определенное среднее значение, а другой запуск того же теста имел совершенно другое просто потому, что JIT обрабатывал вещи по-разному.   -  person Tunaki    schedule 27.01.2016
comment
Отлично - приятно знать - Спасибо, Тунаки. Кстати, я думаю, что этот ответ намного понятнее, чем ссылка, если вы хотите добавить его в качестве ответа.   -  person Ole    schedule 27.01.2016


Ответы (3)


JMH предлагает форк по нескольким причинам. Одним из них является разделение профиля компиляции, как обсуждалось Рафаэлем выше. Но это поведение не контролируется аннотацией @Forks (если только вы не выберете 0 форков, что означает, что никакие подпроцессы вообще не разветвляются для запуска тестов). Вы можете запустить все тесты как часть прогрева теста (таким образом создавая смешанный профиль для работы с JIT), используя элемент управления режимом прогрева (-wm).

Реальность такова, что многие вещи могут сговориться, чтобы так или иначе изменить ваши результаты, и запуск любого теста несколько раз, чтобы установить дисперсию от запуска к запуску, является важной практикой, которую поддерживает JMH (и большинство ручных фреймворков не помогают). . Причины дисперсии между запусками могут включать (но я уверен, что их больше):

  • ЦП запускается в определенном C-состоянии и увеличивает частоту под нагрузкой, затем перегревается и уменьшает ее. Вы можете контролировать эту проблему на определенных ОС.

  • Выравнивание памяти вашего процесса может привести к различиям в поведении страниц.

  • Фоновая активность приложения.
  • Распределение ЦП ОС будет различаться, что приведет к использованию разных наборов ЦП для каждого запуска.
  • Содержимое кэша страниц и подкачка
  • JIT-компиляция запускается одновременно и может привести к другим результатам (обычно это происходит, когда тестируются большие фрагменты кода). Обратите внимание, что небольшие однопоточные тесты обычно не имеют этой проблемы.
  • Поведение GC может срабатывать с немного разными временными интервалами от запуска к запуску, что приводит к разным результатам.

Выполнение вашего теста хотя бы с несколькими разветвлениями поможет избавиться от этих различий и даст вам представление о дисперсии от запуска к запуску, которую вы видите в своем тесте. Я бы порекомендовал вам начать со значения по умолчанию, равного 10, и уменьшить его (или увеличить) экспериментально в зависимости от вашего теста.

person Nitsan Wakart    schedule 02.02.2016

JVM оптимизирует приложение, создавая профиль поведения приложения. Форк создан для сброса этого профиля. В противном случае выполняется:

benchmarkFoo();
benchmarkBar();

могут привести к другим измерениям, чем

benchmarkBar();
benchmarkFoo();

поскольку профиль первого бенчмарка влияет на второй.

Время определяет продолжительность затрат JMH на прогрев или выполнение теста. Если это время слишком мало, ваша виртуальная машина может быть недостаточно прогрета или ваш результат может иметь слишком высокое стандартное отклонение.

person Rafael Winterhalter    schedule 28.01.2016

Обновление:

JMH (Java Microbenchmark Harness) был добавлен в JDK, начиная с JDK 12.

@Fork указывает, как будет происходить выполнение теста, параметр value определяет, сколько раз будет выполняться тест, а параметр warmup определяет, сколько раз тест будет выполняться в пробном режиме, прежде чем будут собраны результаты.

Пример:

@Benchmark
@Fork(value = 1, warmups = 3)
@BenchmarkMode(Mode.AverageTime)
public void myMethod() {
    // Do nothing
}

Это указывает JMH на выполнение трех прогревочных вилок и отбрасывание результатов, прежде чем переходить к тестированию в реальном времени.

person Vishwa Ratna    schedule 15.01.2020