¿Producir código NDK optimizado para múltiples arquitecturas?


Tengo un código C para Android que hace un montón de números de bajo nivel crujido. Me gustaría saber qué ajustes debo usar (por ejemplo, para mi Android.mk y Application.mk) archivos para que el código producido se ejecutará en todos los dispositivos Android actuales, pero también aprovecha las optimizaciones para chipsets específicos. Estoy buscando un buen defecto Android.mk y Application.mk configuración a usar y quiero evitar tener que ensuciar mi código C con ramas # ifdef.

Por ejemplo, soy consciente de que ARMv7 tiene instrucciones de punto flotante y algunos chips ARMv7 soportan instrucciones de NEÓN y que el ARM predeterminado no soporta ninguno de estos. ¿Es posible configurar banderas para que pueda construir ARMv7 con NEÓN, ARMv7 sin NEÓN y la construcción ARM predeterminada? Sé cómo hacer los dos últimos, pero no todos los 3. Soy cauteloso acerca de qué configuración uso, ya que asumo que los valores predeterminados actuales son los ajustes más seguros y qué riesgos tienen otras opciones.

Para la optimización específica de GCC, estoy usando lo siguiente banderas:

LOCAL_CFLAGS=-ffast-math -O3 -funroll-loops

He comprobado los 3 de estos aceleran mi código. ¿Hay otros comunes que pueda añadir?

Otro consejo que tengo es agregar "LOCAL_ARM_MODE: = arm" a Android.mk para permitir una aceleración en los nuevos chips arm (aunque estoy confundido en exactamente lo que esto hace y lo que sucede en los chips más antiguos).

Author: rbcc, 2011-02-23

2 answers

Los procesadores ARM tienen 2 conjuntos de instrucciones generales que soportan: "ARM" y "Thumb". Aunque hay diferentes sabores de ambos, las instrucciones ARM son de 32 bits cada una y las instrucciones Thumb son de 16 bits. La principal diferencia entre los dos es que las instrucciones del BRAZO tienen la posibilidad de hacer más en una sola instrucción que el pulgar. Por ejemplo, una instrucción de un solo BRAZO puede agregar un registro a otro registro, mientras realiza un cambio a la izquierda en el segundo registro. En Pulgar una instrucción tendría que hacer el cambio, luego una segunda instrucción haría la adición.

Las instrucciones del BRAZO no son el doble de buenas, pero en ciertos casos pueden ser más rápidas. Esto es especialmente cierto en el ensamblaje de brazos enrollados a mano, que se puede ajustar de maneras novedosas para hacer el mejor uso de "turnos gratis". Las instrucciones del pulgar tienen su propia ventaja, así como el tamaño: drenan menos la batería.

De todos modos, esto es lo que hace LOCAL_ARM_MODE: significa que compila su código como instrucciones ARM en lugar de instrucciones para el pulgar. Compilar a Thumb es el valor predeterminado en el NDK, ya que tiende a crear un binario más pequeño y la diferencia de velocidad no es tan notable para la mayoría del código. El compilador no siempre puede aprovechar el "empuje" adicional que ARM puede proporcionar, por lo que termina necesitando más o menos el mismo número de instrucciones de todos modos.

El resultado de lo que ves del código de C/C++ compilado para ARM o Thumb será idéntico (salvo errores del compilador).

Esto por sí mismo es compatible entre los procesadores ARM nuevos y antiguos para todos los teléfonos Android disponibles en la actualidad. Esto se debe a que por defecto el NDK compila a una "Interfaz Binaria de Aplicación" para CPU basadas en ARM que soportan el conjunto de instrucciones ARMv5TE. Este ABI se conoce como "armeabi" y se puede establecer explícitamente en el Application.mk poniendo APP_ABI := armeabi.

Los procesadores más nuevos también admiten el ABI específico para Android conocido como armeabi-v7a, que extiende armeabi para agregar el conjunto de instrucciones Thumb-2 y un hardware conjunto de instrucciones de punto flotante llamado VFPv3-D16. las CPU compatibles con armeabi-v7a también pueden soportar opcionalmente el conjunto de instrucciones NEON, que debe verificar en tiempo de ejecución y proporcionar rutas de código para cuando esté disponible y cuando no lo esté. Hay un ejemplo en el directorio NDK / samples que hace esto (hello-neon). Debajo del capó, Thumb-2 es más "BRAZO-como" en que sus instrucciones pueden hacer más en una sola instrucción, mientras que tiene la ventaja de todavía ocupando menos espacio.

En orden para compilar un" binario fat " que contenga las bibliotecas armeabi y armeabi-v7a, debe agregar lo siguiente a Application.mk:

APP_ABI := armeabi armeabi-v7a

Cuando el .el archivo apk está instalado, el administrador de paquetes de Android instala la mejor biblioteca para el dispositivo. Así que en plataformas más antiguas instalaría la biblioteca armeabi, y en dispositivos más nuevos la armeabi-v7a.

Si desea probar las características de la CPU en tiempo de ejecución, puede usar la función NDK uint64_t android_getCpuFeatures() para obtener las características compatibles con el procesador. Esto devuelve un indicador de bits de ANDROID_CPU_ARM_FEATURE_ARMv7 en los procesadores v7a, ANDROID_CPU_ARM_FEATURE_VFPv3 si se admiten puntos flotantes de hardware y ANDROID_CPU_ARM_FEATURE_NEON si se admiten instrucciones SIMD avanzadas. ARM no puede tener NEÓN sin VFPv3.

En resumen: por defecto, sus programas son los más compatibles. El uso de LOCAL_ARM_MODE puede hacer las cosas un poco más rápido a expensas de la duración de la batería debido al uso de instrucciones ARM - y es tan compatible como la configuración predeterminada. Al agregar la línea APP_ABI := armeabi armeabi-v7a, habrá mejorado el rendimiento en los dispositivos más nuevos, siguen siendo compatibles con los más antiguos, pero su .el archivo apk será más grande (debido a que tiene 2 bibliotecas). Para usar las instrucciones de NEON, necesitará escribir código especial que detecte las capacidades de la CPU en tiempo de ejecución, y esto solo se aplica a los dispositivos más nuevos que pueden ejecutar armeabi-v7a.

 112
Author: richq,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 10:29:52

Gran respuesta, al igual que para añadir que debe utilizar

APP_ABI := all

Esto compilará 4 binarios, armv5, armv7, x86 y mips

Es posible que necesite una nueva versión de ndk

 23
Author: user1159819,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-15 19:44:38