Compatibilidade com Neon

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 fornece registros e instruções de escala/vetor (compartilhados com a FPU) comparáveis a MMX/SSE/3DNow! da arquitetura x86.

Nem todos os dispositivos Android baseados em ARMv7 são compatíveis com o Neon, mas aqueles que são podem se beneficiar muito da compatibilidade com instruções de escala/vetor.

Todos os dispositivos 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 por meio da 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 do e a programação de Neon, em geral.

Criar

Como 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"
            }
        }
    }
}

Como 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.

Como 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

Nem todos os dispositivos Android baseados em ARMv7 são compatíveis com o Neon. Para compatibilidade máxima, o código de 32 bits precisa 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 Como lidar com 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).

Código de amostra

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.