elizarov


Блог Романа Елизарова


Previous Entry Share Next Entry
Смотрим на ассемблерный код Java приложения в современном HotSpot-е
elizarov

Я уже писал об универсальном способе просмотра ассемблерного кода Java приложения, что бывает очень полезно при оптимизации производительности. К счастью, в современных версиях HotSpot JVM есть встроенная возможность вывода ассемблерного кода -XX:+PrintAssembly, которая включена даже в production сборку. То есть, можно скачать JDK прямо с сайта и... всё почти заработает, за исключением того, что собственно библиотека дизассемблирования в поставку JDK не входит.

Официальные источники предлагают собрать библиотеку из исходников самим, либо загрузить base-hdis с проекта Kenai, где выложены бинарники под unix-овые операционные системы. К счастью, есть добрая душа, которая выложила hsdis-i386.dll для 32-bit Windows систем здесь, для тех, кому нужно посмотреть на ассемблерный код на типичной desktop машине среднестатистического пользователя.

Собственно, доставание бинарника с дизассемблером и есть самая сложная часть. Дальше, положив его туда, откуда грузит библиотеки ваша JVM, всё становиться очень просто. Я использую вот такую комбинацию ключей при старте JVM:

-XX:+UnlockDiagnosticVMOptions -XX:CompileCommand=print,*<classname>.<methodname> -XX:PrintAssemblyOptions=intel

Где в качестве <classname> и <methodname> указываю имя класса и метода, соответственно, ассемблерный код которого меня интересует в настоящий момент. На x86 архитектуре особо приятно иметь возможность видеть вывод в формате принятым Intel-ом.


  • 1
Спасибо, Рома.

Как раз вчера а JUG говорили с тобой про то, чем заканчивается твой пост по первой ссылке - про SSE-иструкции.

Цитирую пост: "Однако, используя SIMD инструкции из SSE2, доступные начиная с Pentium 4, можно складывать до 4-х 32-битных целых чисел одной инструкцией. Даст ли это заметный прирост в скорости работы? Мы посмотрим на это подробней в ближайшее время."

Каковы результаты? дало прирост? По идее, сложение чисел в цикле идеально ложится на такие инструкции. И если прирост в разы был - интересно, почему в JIT этот трюк не сделан. Или бессмысленно из-за того, что всё равно упрёмся в память?

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

Понятно, что Microsoft может заточить код под винду так, чтобы обыграть джаву на несколько процентов. Но это мелочи. А за счёт чего ещё технология XXX вообще может обыгрывать по производительности джаву в разы?

Edited at 2012-08-24 10:30 am (UTC)

На тесте сложения целых чисел SSE2 никакого прироста не даст, ибо этот тест упирается в память. Чтобы SSE2 давало эффект, надо чтобы была вычислительно-сложная задача. Обычно такие задачи встречаются в мультимедия (обработка изображений и звука) и в физике (в т.ч. в играх).

Видимо, в вычислительно-сложных задачах, про которые ты говоришь, входные и промежуточные данные влезают в кэш.

и я повторю последний вопрос, если ты не против: за счёт чего кроме SSE технология XXX вообще может обыгрывать по производительности джаву в разы?

tail recursion elimination )))

Это всегда можно сделать в коде на любом императивном ЯП.

А Hotspot и javac этого до сих пор не делают afaik.

Я сам могу это сделать. Без их помощи. И всегда так делаю.

Ну еще вещественная арифметика еще не на высоте в Java. Даже без векторных операций и SSE на Java можно проиграть в разы из-за отсутствия доступа ко многим вещественным функциям реализованным аппаратно в процессоре.

1. нативные вставки помогают решить эту проблему?
2. Ты не знаешь, работы по улучшению ситуации с вещественной арифметикой ведутся?

1. Ну нативные вставки вообще любую проблему решат.
2. Не слышал, чтобы этому уделялось внимание.

Это не совсем правда про целые числа. Я на следующее неделе опубликую пост, в котором приведу пример, когда SSE2 дает прирост в два раза. К сожалению, не в четыре, потому что SSE2 операции занимают больше времени.

Если над целыми числами делать неочевидные вычисления, то можно наверняка найти примеры и с бОльшим приростом от SSE. Я лишь говорил про мой примитивный пример, когда тупо запуск в 4 потока позволяет насытить память.

Я про один поток говорил. Дело в том, что, если делать сложения в один поток, то даже в этом случае не получишь выигрыша. Если целые уже легли в кеш - то выигрыш в два раза.

Конечно. Если, например, стоит задача работать с матрицами, то их разбивают на блоки так, чтобы каждый влезал в кэш. Тогда SSE будет давать существенный выигрыш в производительности.

именно. поэтому, нужно аккуратно это формулировать :-) SIMD ускоряет, но не все так просто.

именно. поэтому, нужно аккуратно это формулировать :-) SIMD ускоряет, но не все так просто.

Кул, спасибо. Утащил в загашники.
Кстати, а можно ли в Джаве в явном виде использовать SSE?

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

Поздравляю с днём рождения!

  • 1
?

Log in

No account? Create an account