Подтвердить что ты не робот

Как написать код, чтобы намекнуть на JVM на использование векторных операций?

Совлокальный вопрос и год: Разрабатывают ли какие-либо JIT-компиляторы JVM код с использованием векторизованных инструкций с плавающей запятой?

Предисловие: Я пытаюсь сделать это в чистой java (нет JNI на С++, нет работы GPGPU и т.д.). Я профилировал, и основная часть времени обработки исходит из математических операций в этом методе (что, вероятно, составляет 95% математики с плавающей запятой и 5% целочисленной математики). Я уже уменьшил все вызовы Math.xxx() до приближения, которые достаточно хороши, поэтому большая часть математики теперь с плавающей запятой умножается на несколько добавлений.

У меня есть код, который касается обработки звука. Я делаю трюки и уже наткнулся на большие успехи. Теперь я просматриваю ручную развертку, чтобы увидеть, есть ли какая-либо выгода (по крайней мере, с ручным разворачиванием 2, я вижу примерно 25% -ное улучшение). Пробовав мою руку при ручном разворачивании 4 (что начинает очень сложно, так как я разворачиваю обе петли вложенного цикла), мне интересно, есть ли что-нибудь, что я могу сделать, чтобы намекнуть на jvm, что во время выполнения он может использовать вектор (например, SSE2, AVX и т.д.). Каждый образец аудио может быть рассчитан полностью независимо от других образцов, поэтому я уже смог увидеть улучшение на 25% (уменьшая количество зависимостей от вычислений с плавающей запятой).

Например, у меня есть 4 поплавки, по одному для каждого из 4 разворот цикла, чтобы удерживать частично вычисленное значение. Как я заявляю и использую эти поплавки? Если я сделаю это float [4], это намекает на jvm, что они не связаны друг с другом vs с float, float, float, float или даже с классом из 4 общедоступных плавающих точек? Есть ли что-то, что я могу сделать без смысла, что убьет мой шанс на векторизованный код?

Я столкнулся с статьями онлайн о написании кода "нормально", потому что компилятор /jvm знает общие шаблоны и как их оптимизировать, а отклонение от шаблонов может означать меньшую оптимизацию. По крайней мере, в этом случае, однако, я бы не ожидал, что разворачивает циклы на 2, чтобы улучшить производительность, насколько это было возможно. Мне интересно, есть ли что-нибудь еще, что я могу сделать (или, по крайней мере, не делать), чтобы помочь мне шансы. Я знаю, что компилятор /jvm только поправится, поэтому я также хочу быть осторожным в том, чтобы делать что-то, что повредит мне в будущем.

Отредактируйте для любопытных: разворачивание на 4 увеличилось на 25% за разматывание на 2, поэтому я действительно думаю, что векторные операции помогут в моем случае, если jvm поддерживает его (или, возможно, уже использует их).

Спасибо!

4b9b3361

Ответ 1

Как я могу обрабатывать музыку..pure java (без JNI на С++, без GPGPU и т.д.)... использовать векторные операции (например, SSE2, AVX и т.д.)

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

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

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

Даже С++ (считается быстрым языком) не будет автоматически использовать некоторые супер оптимизированные аппаратные операции для вас. Он может просто встроить один из нескольких методов языка ассемблера ручной работы в определенных местах.

Итак, я отвечаю, что существует "возможно, нет способа" , чтобы дать JVM возможность использовать некоторую оптимизацию оборудования для вашего кода (например, SSE), и даже если бы существовало некоторое время, то время выполнения Java-языка все равно будет иметь слишком много других факторов, которые замедлят ваш код.

Используйте низкоуровневый язык, предназначенный для этой задачи, и привяжите его к Java для высокоуровневой логики.

EDIT: добавление дополнительной информации на основе комментариев

Если вы уверены, что высокоуровневая "запись когда-нибудь запускается где угодно", языковая среда исполнения определенно должна также выполнять множество оптимизаций низкого уровня для вас и автоматически включать ваш высокоуровневый код в оптимизированный низкоуровневый код, тогда... Оптимизация компилятора JIT зависит от реализации виртуальной машины Java. Их много.

В случае Oracle JVM (HotSpot) вы можете начать искать свой ответ скачать исходный код, текст SSE2 появится в следующем файлы:

  • OpenJDK/точка доступа/SRC/процессор/x86/VM/assembler_x86.cpp
  • OpenJDK/точка доступа/SRC/процессор/x86/VM/assembler_x86.hpp
  • OpenJDK/точка доступа/SRC/процессор/x86/VM/c1_LIRGenerator_x86.cpp
  • OpenJDK/точка доступа/SRC/процессор/x86/VM/c1_Runtime1_x86.cpp
  • OpenJDK/точка доступа/SRC/процессор/x86/VM/sharedRuntime_x86_32.cpp
  • OpenJDK/точка доступа/SRC/процессор/x86/VM/vm_version_x86.cpp
  • OpenJDK/точка доступа/SRC/процессор/x86/VM/vm_version_x86.hpp
  • OpenJDK/точка доступа/SRC/процессор/x86/VM/x86_32.ad
  • OpenJDK/точка доступа /SRC/os _cpu/linux_x86/VM/os_linux_x86.cpp
  • OpenJDK/точка доступа/SRC/доля/VM/c1/c1_GraphBuilder.cpp
  • OpenJDK/точка доступа/SRC/доля/VM/c1/c1_LinearScan.cpp
  • OpenJDK/точка доступа/SRC/доля/VM/выполнения/globals.hpp

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

Я бы не стал охотиться за этим даже с +500 баунти. ИМХО, вопрос неправильный, основанный на неправильных предположениях

Ответ 2

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

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

Трудно дать вам более конкретную обратную связь с некоторым кодом. Я предлагаю вам взять рассматриваемый цикл и представить его в тесте JMH. Это облегчает анализ и обсуждение.

Ответ 3

Похоже, что оптимизация SIMD/SSE была сделана в Java 8/9.