sugerir puedo para opcion hago hace desde cómo como celular aparece amigos java performance jvm-hotspot

java - puedo - cómo se hace para sugerir amigos en el facebook



¿Cómo puedo escribir código para sugerir a la JVM que utilice operaciones vectoriales? (3)

Pregunta un tanto relacionada y de un año de antigüedad: ¿Los compiladores JIT de JVM generan código que utiliza instrucciones vectorizadas de punto flotante?

Prefacio: Estoy tratando de hacer esto en java puro (sin JNI a C ++, no funciona GPGPU, etc.). He perfilado y la mayor parte del tiempo de procesamiento proviene de las operaciones matemáticas en este método (que probablemente es un 95% de matemáticas de punto flotante y un 5% de matemáticas de enteros). Ya reduje todas las llamadas de Math.xxx () a una aproximación que es lo suficientemente buena, por lo que la mayoría de las matemáticas ahora se multiplican en coma flotante con algunas adiciones.

Tengo un código que se ocupa del procesamiento de audio. He estado haciendo ajustes y ya he encontrado grandes avances. Ahora estoy investigando el desenrollamiento manual de bucles para ver si hay algún beneficio (al menos con un desenrollamiento manual de 2, veo una mejora de aproximadamente el 25%). Mientras intento un desenrollamiento manual de 4 (lo que está empezando a complicarse ya que estoy desenrollando ambos bucles de un bucle anidado) me pregunto si hay algo que pueda hacer para sugerir al JVM que en tiempo de ejecución puede usar vector operaciones (por ejemplo, SSE2, AVX, etc ...). Cada muestra del audio se puede calcular de forma completamente independiente de otras muestras, por lo que ya he podido ver una mejora del 25% (reduciendo la cantidad de dependencias en los cálculos de punto flotante).

Por ejemplo, tengo 4 flotadores, uno para cada uno de los 4 desenrollamientos del bucle para mantener un valor parcialmente calculado. ¿Importa cómo declaro y uso estos flotadores? Si lo hago flotar [4], ¿eso sugiere a la JVM que no están relacionados entre sí o que tienen flotar, flotar, flotar, flotar o incluso una clase de 4 flotadores públicos? ¿Hay algo que pueda hacer sin sentido para matar mi oportunidad de vectorizar el código?

He encontrado artículos en línea sobre cómo escribir código "normalmente" porque el compilador / jvm conoce los patrones comunes y cómo optimizarlos y desviarse de los patrones puede significar menos optimización. Sin embargo, al menos en este caso, no hubiera esperado que el desenrollar los bucles por 2 hubiera mejorado el rendimiento tanto como lo hizo, así que me pregunto si hay algo más que pueda hacer (o al menos no ) para ayudar a mi posibilidades Sé que el compilador / jvm solo va a mejorar, así que también quiero tener cuidado de hacer cosas que me lastimarán en el futuro.

Edite para los curiosos: desenrollar en 4 un mayor rendimiento en otro ~ 25% sobre desenrollar en 2, así que realmente creo que las operaciones vectoriales serían útiles en mi caso si el JVM lo apoyara (o quizás ya lo esté usando).

¡Gracias!


Cómo puedo ... procesar audio ... Java puro (sin JNI a C ++, no funciona GPGPU, etc ...) .. utilizar operaciones vectoriales (por ejemplo, SSE2, AVX, etc.)

Java es un lenguaje de alto nivel (una instrucción en Java genera muchas instrucciones de hardware) que no es adecuada para el diseño (por ejemplo, la gestión de memoria del recolector de basura) para tareas que manipulan grandes volúmenes de datos en tiempo real.

Por lo general, hay piezas especiales de hardware optimizadas para un rol particular (por ejemplo, procesamiento de imágenes o reconocimiento de voz ) que muchas veces utilizan paralelización a través de varias líneas de procesamiento simplificadas.

También hay lenguajes de programación especiales para este tipo de tareas, principalmente lenguajes de descripción de hardware y lenguaje ensamblador .

Incluso C ++ (considerado el lenguaje rápido) no utilizará automáticamente para usted algunas operaciones de hardware súper optimizadas. Puede simplemente incluir uno de los varios métodos de lenguaje ensamblador hechos a mano en ciertos lugares.

Así que mi respuesta es que "probablemente no hay manera" de instruir a JVM para que use alguna optimización de hardware para su código (por ejemplo, SSE ) e incluso si hubiera alguna, entonces el tiempo de ejecución del lenguaje Java todavía tendría demasiados otros factores que disminuirán la velocidad. tu codigo.

Utilice un lenguaje de bajo nivel diseñado para esta tarea y vincúlelo a Java para obtener una lógica de alto nivel.

EDITAR: añadir más información basada en comentarios

Si está convencido de que el tiempo de ejecución de lenguaje de "escritura una vez que se ejecuta una ejecución de alto nivel" también debería realizar muchas optimizaciones de bajo nivel y convertir automáticamente su código de alto nivel en código de bajo nivel optimizado, entonces ... la forma en que el compilador JIT optimiza Depende de la implementación de la Máquina Virtual Java . Hay muchos de ellos.

En el caso de Oracle JVM (HotSpot) puede comenzar a buscar su respuesta descargando el código fuente , el texto SSE2 aparece en los siguientes archivos:

  • openjdk / hotspot / src / cpu / x86 / vm / assembler_x86.cpp
  • openjdk / hotspot / src / cpu / x86 / vm / assembler_x86.hpp
  • openjdk / hotspot / src / cpu / x86 / vm / c1_LIRGenerator_x86.cpp
  • openjdk / hotspot / src / cpu / x86 / vm / c1_Runtime1_x86.cpp
  • openjdk / hotspot / src / cpu / x86 / vm / sharedRuntime_x86_32.cpp
  • openjdk / hotspot / src / cpu / x86 / vm / vm_version_x86.cpp
  • openjdk / hotspot / src / cpu / x86 / vm / vm_version_x86.hpp
  • openjdk / hotspot / src / cpu / x86 / vm / x86_32.ad
  • openjdk / hotspot / src / os_cpu / linux_x86 / vm / os_linux_x86.cpp
  • openjdk / hotspot / src / share / vm / c1 / c1_GraphBuilder.cpp
  • openjdk / hotspot / src / share / vm / c1 / c1_LinearScan.cpp
  • openjdk / hotspot / src / share / vm / runtime / globals.hpp

Están en C ++ y en lenguaje ensamblador, por lo que tendrá que aprender algunos idiomas de bajo nivel para leerlos de todos modos.

No cazaría tan profundo ni siquiera con una recompensa de +500. En mi humilde opinión la pregunta es incorrecta basada en suposiciones erróneas


Las optimizaciones de SuperWord en Hotspot son limitadas y bastante frágiles. Limitados, ya que generalmente están detrás de lo que ofrece un compilador de C / C ++ y frágiles, ya que dependen de formas de bucle particulares (y solo son compatibles con ciertas CPU).

Entiendo que quieres escribir una vez ejecutado en cualquier lugar. Parece que ya tienes una solución Java pura. Es posible que desee considerar una implementación opcional para plataformas populares conocidas para complementar esa implementación a "rápido en algunos lugares", lo que probablemente ya sea cierto.

Es difícil darte comentarios más concretos con algún código. Le sugiero que tome el bucle en cuestión y lo presente en un punto de referencia JMH. Esto hace que sea fácil de analizar y discutir.


Parece que se hicieron muchas optimizaciones de SIMD / SSE en Java 8/9 .