Процессы производительности Java против потоков - PullRequest
14 голосов
/ 26 октября 2011

Я реализую рабочий пул в Java.

Это, по сути, целая нагрузка объектов, которые будут собирать порции данных, обрабатывать данные и затем сохранять результат.Из-за задержки ввода-вывода будет значительно больше рабочих, чем процессорных ядер.

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

Самой простой реализацией было бы иметь один Java-процесс, который создает и контролирует несколько рабочих потоков.Альтернативой может быть запуск процесса Java для каждого работника.

Предполагая, что в качестве аргументов используется сервер Linux с четырьмя ядрами, какое из этих решений вы ожидаете, чтобы быть более производительным и почему?

Можно предположить, что работникам никогда не нужно общаться друг с другом.

Ответы [ 3 ]

18 голосов
/ 26 октября 2011

Один процесс, несколько потоков - по нескольким причинам.

При переключении контекста между заданиями на некоторых процессорах дешевле переключаться между потоками, чем между процессами. Это особенно важно в случае такого рода операций ввода-вывода с большим количеством рабочих, чем ядер. Чем больше работы вы выполняете между блокировкой ввода / вывода, тем менее важно это. Хорошая буферизация окупит потоки или процессов.

При переключении между потоками в одной и той же JVM, по крайней мере, некоторые реализации Linux (в частности, x86) не должны очищать кэш. См. Блог Тсуны . Загрязнение кэша между потоками будет сведено к минимуму, поскольку они могут совместно использовать программный кэш, выполняют одну и ту же задачу и совместно используют одну и ту же копию кода. Мы говорим об экономии от порядка сотен наносекунд до нескольких микросекунд на коммутатор. Если это маленькая картошка для вас, тогда читайте дальше ...

В зависимости от конструкции путь данных ввода / вывода может быть короче для одного процесса.

Время запуска и прогрева потока обычно намного короче. ОС не должна запускать процесс, Java не должна запускать другую JVM, загрузка классов выполняется только один раз, JIT-компиляция выполняется только один раз, а оптимизация HotSpot выполняется один раз и раньше.

16 голосов
/ 26 октября 2011

Ну, обычно при обсуждении многопоточности (/ w один поток на процесс) в сравнении с многопоточностью в одном и том же процессе, в то время как теоретические издержки в первом случае больше, чем во втором (и, следовательно, многопроцессорность теоретически медленнее, чем мульти на самом деле на большинстве современных ОС это не такая большая проблема. Однако при обсуждении этого в контексте Java запуск нового процесса обходится намного дороже, чем запуск нового потока. Запуск нового процесса означает запуск нового экземпляра JVM, который очень дорог, особенно с точки зрения памяти. Я рекомендую вам запустить несколько потоков в одной и той же JVM.

Более того, если вы говорите, что межпотоковое взаимодействие не является проблемой, вы можете использовать Служба исполнения Java , чтобы получить фиксированный пул потоков размером 2x (количество доступных процессоров). Количество доступных процессоров может быть автоматически определено во время выполнения с помощью Java-класса Runtime. Таким образом, вы получите быструю простую многопоточность без кода котельной пластины.

0 голосов
/ 06 мая 2017

На самом деле, если вы делаете это с большими масштабами, использование нескольких jvm процессов намного быстрее, чем одного jvm с несколькими потоками.По крайней мере, у нас никогда не было одного запуска jvm так же быстро, как и нескольких jvms.

Мы проводим некоторые вычисления, в которых каждая задача использует около 2-3 ГБ ОЗУ и выполняет некоторые сложные вычисления.Если мы создадим 30 JVM и выполним 30 задач, они будут работать примерно на 15-20% лучше, чем 30 потоков в одном JVM.Мы попытались настроить gc и различные разделы памяти и никогда не подходили к первому варианту.

Мы делали это на разных машинах 14 задач на 16-ядерном сервере, 34 задачи на 36-ядерном сервере и т. Д.Java всегда выполнял больше, чем несколько процессов jvm.

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

...