Menangani fitur-fitur CPU

ABI: menggunakan makro bawaan preprosesor

Biasanya, ABI paling mudah ditentukan saat membuat build menggunakan #ifdef bersama dengan:

  • __arm__ untuk ARM 32-bit
  • __aarch64__ untuk ARM 64-bit
  • __i386__ untuk X86 32-bit
  • __x86_64__ untuk X86 64-bit

Perhatikan bahwa X86 32-bit disebut __i386__, bukan __x86__ seperti yang mungkin Anda kira.

Jumlah inti CPU: menggunakan sysconf(3) libc

sysconf(3) memungkinkan Anda mengkueri _SC_NPROCESSORS_CONF (jumlah inti CPU dalam sistem) dan juga _SC_NPROCESSORS_ONLN (jumlah inti CPU yang sedang online).

Fitur: menggunakan getauxval(3) libc

Mulai API level 18, getauxval(3) tersedia pada library C Android. Argumen AT_HWCAP dan AT_HWCAP2 menampilkan bitmask yang mencantumkan fitur khusus CPU. Lihat berbagai header hwcap.h di NDK untuk digunakan sebagai pembanding konstanta, seperti HWCAP_SHA512 untuk instruksi SHA512 arm64, atau HWCAP_IDIVT untuk instruksi pembagian bilangan bulat Thumb arm.

Library cpu_features Google

Salah satu masalah dengan AT_HWCAP adalah terkadang beberapa perangkat mengalami kesalahan. Beberapa perangkat lama, misalnya, mengklaim memiliki instruksi pembagian bilangan bulat, padahal tidak.

Library cpu_features Google mengatasi masalah ini dengan menerapkan pengetahuannya tentang SoC tertentu (dengan mengurai /proc/cpuinfo untuk menyelesaikan SoC spesifik yang dimaksud).

Solusi alternatifnya adalah dengan menginstal pengendali sinyal untuk SIGILL dan mencoba menjalankan instruksi yang dimaksud. Sebagai contoh, BoringSSL/OpenSSL menggunakan teknik ini.

Library cpufeatures NDK

NDK menyediakan library kecil bernama cpufeatures yang menawarkan fungsionalitas yang mirip dengan getauxval(3), tetapi juga dapat digunakan pada level API di bawah 18. Tidak seperti library cpu_features lainnya, library ini tidak memiliki pengetahuan ekstra tentang SoC tertentu.

API cpufeatures NDK

uint64_t android_getCpuFeatures();
    

Menampilkan kumpulan tanda bit, di mana setiap tanda mewakili satu fitur khusus kelompok CPU. Bagian selanjutnya dalam bagian ini memberikan informasi tentang fitur untuk masing-masing kelompok CPU.

Kelompok CPU ARM 32-bit

Tanda berikut tersedia untuk kelompok CPU ARM 32-bit:

ANDROID_CPU_ARM_FEATURE_VFPv2
Menunjukkan bahwa CPU perangkat mendukung set instruksi VFPv2. Sebagian besar CPU ARMv6 mendukung set instruksi ini.
ANDROID_CPU_ARM_FEATURE_ARMv7
Menunjukkan bahwa CPU perangkat mendukung set instruksi ARMv7-A yang didukung oleh ABI armeabi-v7a. Set instruksi ini mendukung instruksi Thumb-2 dan juga VFPv3-D16. Nilai yang ditampilkan ini juga menunjukkan dukungan untuk ekstensi set instruksi FPU hardware VFPv3.
ANDROID_CPU_ARM_FEATURE_VFPv3
Menunjukkan bahwa CPU perangkat mendukung ekstensi set instruksi FPU hardware VFPv3.

Nilai ini setara dengan set instruksi VFPv3-D16, yang hanya menyediakan register FP presisi ganda hardware 16-bit.

ANDROID_CPU_ARM_FEATURE_VFP_D32
Menunjukkan bahwa CPU perangkat mendukung register FP presisi ganda hardware 32-bit, bukan 16-bit. Meskipun ada register FP presisi ganda hardware 32-bit, masih ada register presisi tunggal 32-bit yang dipetakan ke bank register yang sama.
ANDROID_CPU_ARM_FEATURE_NEON
Menunjukkan bahwa CPU perangkat mendukung ekstensi set instruksi vektor ARM Advanced SIMD (NEON). Perhatikan bahwa ARM memerintahkan agar CPU tersebut juga mengimplementasikan VFPv3-D32, yang menyediakan register FP hardware 32-bit (digunakan bersama dengan unit NEON).
ANDROID_CPU_ARM_FEATURE_VFP_FP16
Menunjukkan bahwa CPU perangkat mendukung instruksi untuk menjalankan operasi floating-point (bilangan titik mengambang) pada register 16-bit. Fitur ini adalah bagian dari spesifikasi VFPv4.
ANDROID_CPU_ARM_FEATURE_VFP_FMA
Menunjukkan bahwa CPU perangkat mendukung ekstensi akumulasi-berlipat gabungan untuk set instruksi VFP. Juga bagian dari spesifikasi VFPv4.
ANDROID_CPU_ARM_FEATURE_NEON_FMA
Menunjukkan bahwa CPU perangkat mendukung ekstensi akumulasi-berlipat gabungan untuk set instruksi NEON. Juga bagian dari spesifikasi VFPv4.
ANDROID_CPU_ARM_FEATURE_IDIV_ARM
Menunjukkan bahwa CPU perangkat mendukung pembagian bilangan bulat dalam mode ARM. Hanya tersedia pada CPU model terbaru, seperti Cortex-A15.
ANDROID_CPU_ARM_FEATURE_IDIV_THUMB2
Menunjukkan bahwa CPU perangkat mendukung pembagian bilangan bulat dalam mode Thumb-2. Hanya tersedia pada CPU model terbaru, seperti Cortex-A15.
ANDROID_CPU_ARM_FEATURE_iWMMXt
Menunjukkan bahwa CPU perangkat mendukung ekstensi set instruksi yang menambahkan instruksi dan register MMX. Fitur ini hanya tersedia di beberapa CPU berbasis XScale.
ANDROID_CPU_ARM_FEATURE_LDREX_STREX
Menunjukkan bahwa CPU perangkat mendukung instruksi LDREX dan STREX yang tersedia mulai ARMv6. Secara bersamaan, instruksi ini memberikan update menyeluruh pada memori dengan bantuan monitor eksklusif.

Kelompok CPU ARM 64-bit

Tanda berikut tersedia untuk kelompok CPU ARM 64-bit:

ANDROID_CPU_ARM64_FEATURE_FP
Menunjukkan bahwa CPU perangkat memiliki Floating Point Unit (FPU). Semua perangkat Android ARM64 harus mendukung fitur ini.
ANDROID_CPU_ARM64_FEATURE_ASIMD
Menunjukkan bahwa CPU perangkat memiliki unit Advanced SIMD (ASIMD). Semua perangkat Android ARM64 harus mendukung fitur ini.
ANDROID_CPU_ARM64_FEATURE_AES
Menunjukkan bahwa CPU perangkat mendukung instruksi AES.
ANDROID_CPU_ARM64_FEATURE_CRC32
Menunjukkan bahwa CPU perangkat mendukung instruksi CRC32.
ANDROID_CPU_ARM64_FEATURE_SHA1
Menunjukkan bahwa CPU perangkat mendukung instruksi SHA1.
ANDROID_CPU_ARM64_FEATURE_SHA2
Menunjukkan bahwa CPU perangkat mendukung instruksi SHA2.
ANDROID_CPU_ARM64_FEATURE_PMULL
Menunjukkan bahwa CPU perangkat mendukung instruksi PMULL dan PMULL2 64-bit.

Kelompok CPU x86 32-bit

Tanda berikut tersedia untuk kelompok CPU x86 32-bit.

ANDROID_CPU_X86_FEATURE_SSSE3
Menunjukkan bahwa CPU perangkat mendukung set ekstensi instruksi SSSE3.
ANDROID_CPU_X86_FEATURE_POPCNT
Menunjukkan bahwa CPU perangkat mendukung instruksi POPCNT.
ANDROID_CPU_X86_FEATURE_MOVBE
Menunjukkan bahwa CPU perangkat mendukung instruksi MOVBE. Instruksi ini khusus untuk beberapa CPU Intel IA-32, seperti Atom.

android_getCpuFeatures() menampilkan 0 untuk kelompok CPU yang tidak memiliki ekstensi yang tercantum.

int android_getCpuCount(void);
    

Menampilkan jumlah inti CPU dalam sistem, yang mungkin lebih tinggi daripada jumlah yang sebenarnya online.

AndroidCpuFamily android_getCpuFamily();
    

Menampilkan salah satu konstanta berikut yang mewakili kelompok/arsitektur CPU yang didukung perangkat:

  • ANDROID_CPU_FAMILY_ARM
  • ANDROID_CPU_FAMILY_X86
  • ANDROID_CPU_FAMILY_ARM64
  • ANDROID_CPU_FAMILY_X86_64

Untuk executable 32-bit pada sistem 64-bit, fungsi ini menampilkan arsitektur 32-bit.

Menggunakan cpufeatures NDK dengan ndk-build

Library cpufeatures tersedia sebagai modul impor. Untuk menggunakannya:

  • Tambahkan cpufeatures ke LOCAL_STATIC_LIBRARIES.

  • #include <cpu-features.h> dalam kode sumber Anda.

  • Impor android/cpufeatures di akhir Android.mk Anda.

Berikut adalah contoh Android.mk yang mengimpor cpufeatures:

LOCAL_PATH := $(call my-dir)

    include $(CLEAR_VARS)
    LOCAL_MODULE := your-module-name
    LOCAL_SRC_FILES := ...
    LOCAL_STATIC_LIBRARIES := cpufeatures
    include $(BUILD_SHARED_LIBRARY)

    $(call import-module,android/cpufeatures)