O NDK é compatível com o ARM Advanced SIMD, mais conhecido como Neon, uma extensão de conjunto de instruções opcional para ARMv7 e ARMv8. O Neon oferece registros e instruções de escala/vetor (compartilhados com a FPU) comparáveis a MMX/SSE/3DNow! da arquitetura x86.
Quase todos os dispositivos Android baseados em ARMv7 são compatíveis com o Neon, incluindo todos os dispositivos com API de nível 21 ou mais recente. O NDK ativa o Neon por padrão.
Todos os dispositivos Android baseados em ARMv8 são compatíveis com o Neon.
O NDK permite a compilação de módulos ou até arquivos de origem específicos pela compatibilidade com o Neon. Você pode usar os intrínsecos do Neon (link em inglês) no código C e C++ para aproveitar a extensão Advanced SIMD. O Guia do programador do Neon para Armv8-A (link em inglês) traz mais informações específicas sobre os intrínsecos e a programação do Neon, em geral.
Criar
Ativar o Neon globalmente
ndk-build
O ndk-build não é compatível com a ativação do Neon globalmente. Para ativar o Neon em todo o app ndk-build, aplique as etapas a cada módulo no app.
CMake
Transmita -DANDROID_ARM_NEON=ON
ao invocar o CMake. Ao criar com o Android
Studio/Gradle, defina a seguinte opção no build.gradle:
android {
defaultConfig {
externalNativeBuild {
cmake {
arguments "-DANDROID_ARM_NEON=ON"
}
}
}
}
Ativar o Neon por módulo
ndk-build
Para criar todos os arquivos de origem em um módulo ndk-build com NEON, adicione o seguinte à definição do módulo no Android.mk:
LOCAL_ARM_NEON := true
CMake
Para criar todos os arquivos de origem em um destino do CMake com NEON, adicione o seguinte ao CMakeLists.txt:
if(ANDROID_ABI STREQUAL armeabi-v7a)
set_target_properties(${TARGET} PROPERTIES COMPILE_FLAGS -mfpu=neon)
endif()
Em que ${TARGET}
é substituído pelo nome da sua biblioteca.
Ela poderá ser usada principalmente para criar todos os arquivos de origem que tenham compatibilidade com Neon se você quiser criar uma biblioteca estática ou compartilhada que contenha, especificamente, código apenas Neon.
Ativar o Neon por arquivo de origem
ndk-build
Ao listar arquivos de origem para a variável LOCAL_SRC_FILES
, você tem a opção de usar o sufixo .neon
para indicar que quer criar arquivos individuais compatíveis com o Neon. Por exemplo, o seguinte cria um arquivo (foo.c
) compatível com o Neon e outro (bar.c
) sem compatibilidade:
LOCAL_SRC_FILES := foo.c.neon bar.c
É possível combinar o sufixo .neon
com o .arm
, que especifica o conjunto de instruções ARM de 32 bits, em vez do Thumb2, para instruções para não Neon.
Nesse caso, .arm
precisa vir antes de .neon
. Por exemplo: foo.c.arm.neon
funciona, mas foo.c.neon.arm
não.
CMake
Para criar um arquivo de origem específico com o Neon, adicione o seguinte ao CMakeLists.txt:
if(ANDROID_ABI STREQUAL armeabi-v7a)
set_source_files_properties(foo.cpp PROPERTIES COMPILE_FLAGS -mfpu=neon)
endif()
Detecção do ambiente de execução
Quase todos os dispositivos Android baseados em ARMv7 são compatíveis com o Neon, incluindo todos os dispositivos com API de nível 21 ou mais recente. O NDK ativa o Neon por padrão. Para compatibilidade máxima, o código de 32 bits pode realizar detecção no ambiente de execução para confirmar se o código NEON pode ser executado no dispositivo de destino. O app pode realizar essa verificação usando qualquer uma das opções mencionadas em Recursos da CPU.
Como alternativa, é possível filtrar dispositivos incompatíveis no Google Play Console. Você também pode usar o console para ver quantos dispositivos isso afetaria.
Compatibilidade entre plataformas para x86
O NDK é compatível com a compilação entre plataformas das funções intrínsecas ARM SIMD (Neon) existentes para o código SSE x86 por meio do uso de NEON_2_SSE.h de terceiros. Para mais informações sobre esse assunto, consulte Do ARM NEON para o Intel SSE: a solução de portabilidade automática, dicas e sugestões (links em inglês).
Exemplo de código
A amostra hello-neon (link em inglês)
traz um exemplo de como usar a biblioteca cpufeatures
e intrínsecos do Neon
ao mesmo tempo. Essa amostra implementa um pequeno comparativo para um loop de filtro FIR com uma versão C, além de implementar uma versão otimizada para Neon para dispositivos compatíveis com Neon.