Почему 64-битная JVM быстрее, чем 32-битная? - PullRequest
14 голосов
/ 08 февраля 2011

Недавно я провел некоторые тесты производительности записи в базе данных моей компании, и обнаружил, что простое переключение на 64-битную JVM дает стабильное увеличение производительности на 20-30%.

Мне не разрешено вдаваться в подробности о нашем продукте, но в основном это БД, ориентированная на столбцы, оптимизированная для хранения журналов. Тестирование включает подачу нескольких гигабайт необработанных журналов и определение времени, необходимого для их анализа и хранения в виде структурированных данных в БД. Обработка очень тяжелая как для процессора, так и для ввода-вывода, хотя трудно сказать, в каком соотношении.

Несколько замечаний по настройке:

Processor: Xeon E5640 2.66GHz (4 core) x 2
RAM: 24GB
Disk: 7200rpm, no RAID
OS: RHEL 6 64bit
Filesystem: Ext4
JVMs: 1.6.0_21 (32bit), 1.6.0_23 (64bit)
Max heap size (-Xmx): 512 MB (for both 32bit and 64bit JVMs)

Константы для обеих JVM:

  • Та же ОС (64-битная RHEL)
  • То же оборудование (64-битный процессор)
  • Максимальный размер кучи установлен на 512 МБ (поэтому увеличение скорости не происходит из-за 64-битной JVM, использующей большую кучу)

Для простоты я отключил все возможности многопоточности в нашем продукте, поэтому почти вся обработка выполняется однопоточным способом. (Когда я включил многопоточность, конечно, система стала быстрее, но соотношение между 32-битной и 64-битной производительностью осталось примерно таким же.)

Итак, мой вопрос ... Почему я вижу улучшение скорости на 20-30% при использовании 64-битной JVM? Кто-нибудь видел подобные результаты раньше?

Моя интуиция до сих пор была следующей:

  • 64-битные указатели больше, поэтому кэши L1 и L2 легче переполняются, поэтому производительность на 64-битной JVM хуже.

  • JVM использует некоторые хитрые приемы сжатия указателей, чтобы максимально облегчить вышеуказанную проблему. Подробности на сайте Sun здесь .

  • JVM разрешено использовать больше регистров при работе в 64-битном режиме, что немного ускоряет процесс.

Учитывая вышеперечисленные три пункта, я ожидал бы, что 64-битная производительность будет немного медленнее или приблизительно равна 32-битной JVM.

Есть идеи? Заранее спасибо.

Редактировать: Разъяснил некоторые моменты о тестовой среде.

Ответы [ 5 ]

10 голосов
/ 08 февраля 2011

From: http://www.oracle.com/technetwork/java/hotspotfaq-138619.html#64bit_performance

"Как правило, преимущества адресации больших объемов памяти приводят к небольшой потере производительности в 64-разрядных виртуальных машинах по сравнению с запуском того же приложения на 32-разрядной виртуальной машинеЭто связано с тем, что каждый собственный указатель в системе занимает 8 байтов вместо 4. Загрузка этих дополнительных данных влияет на использование памяти, что приводит к немного более медленному выполнению в зависимости от того, сколько указателей загружено во время выполнения.вашей программы на Java. Хорошая новость заключается в том, что на платформах AMD64 и EM64T, работающих в 64-битном режиме, Java VM получает несколько дополнительных регистров, которые можно использовать для генерации более эффективных последовательностей собственных команд.при сравнении 32- и 64-битной скорости выполнения часто не происходит вообще никакой потери производительности.
Разница в производительности при сравнении приложения, работающего на 64-битной платформе, с 32-битной платформой на SPARC составляет порядка 10-20.% деградации, когдавы переходите на 64-битную виртуальную машину.На платформах AMD64 и EM64T эта разница колеблется от 0 до 15% в зависимости от количества указателей, обращающихся к вашему приложению. "

8 голосов
/ 08 февраля 2011

Не зная вашего аппаратного обеспечения, я просто беру некоторые дикие удары

  • Ваш конкретный ЦП может использовать микрокод для «эмуляции» некоторых инструкций x86 - в особенности x87 ISA
  • x64 использует sse math вместо x87 math, в этом случае я заметил ускорение некоторых приложений C ++ с большим математическим расчетом на% 10- 20.Математические различия могут стать настоящим убийцей, если вы используете strictfp.
  • Память.64 бита дает вам гораздо больше адресного пространства.Может быть, GC немного менее агрессивен в 64-битном режиме, потому что у вас есть дополнительная оперативная память.
  • Ваша ОС работает в 64-битном режиме и работает с 32-битной jvm через какую-то служебную программу-обертку?
2 голосов
/ 08 февраля 2011

Моя лучшая догадка, основанная на быстром гугле для 32- и 64-битных графиков производительности, является то, что 64-битный ввод-вывод более эффективен. Я полагаю, вы делаете много операций ввода-вывода ...

Если при перемещении данных используется memcpy, возможно, более эффективно копировать длинные, чем целые.

2 голосов
/ 08 февраля 2011

В 64-битном наборе команд есть еще 8 регистров, что должно в целом ускорить код.

Но, поскольку процессоры в настоящее время в основном ждут память или диск, я предполагаю, что подсистема памяти или дисковый ввод-вывод могут быть более эффективными в 64-битном режиме.

1 голос
/ 08 февраля 2011

Поймите, что 64-битная JVM - это не волшебная пыль, которая заставляет приложения Java работать быстрее.64-разрядная JVM допускает кучу >> 4 ГБ и, как таковая, имеет смысл только для приложений, которые могут использовать преимущества огромной памяти в системах, в которых она есть.

Как правило, есть или небольшое улучшение (из-заопределенные аппаратные оптимизации на определенных платформах) или незначительное ухудшение (из-за увеличенного размера указателя).Вообще говоря, потребуется меньшее количество сборщиков мусора, но когда они произойдут, они, вероятно, будут длиннее.

В базах данных памяти или поисковых системах, которые могут использовать увеличенную память для кэширования объектов и, таким образом, избегать доступа к IPC или диску, будут наблюдаться самые большие улучшения на уровне приложений.Кроме того, 64-битная JVM также позволит вам запускать много, намного больше потоков, чем 32-битный, потому что есть больше адресного пространства для таких вещей, как стеки потоков и т. Д. Максимальное количество потоков обычно для 32-битной JVMЭто ~ 1000, но ~ 100000 потоков с 64-битной JVM.

Однако есть некоторые недостатки:
Дополнительные проблемы с 64-битной JVM заключаются в том, что некоторые ориентированные на клиента функции, такие как Java Plug-in и Java Web Start,не поддерживается.Также любой собственный код также должен быть совместимым (например, JNI для таких вещей, как драйверы JDBC типа II).Это бонус для разработчиков на чистом Java, поскольку чистые приложения должны просто запускаться из коробки.

Подробнее об этой теме на Java.net

...