web-dev-qa-db-ja.com

複数のアーキテクチャ向けに最適化されたNDKコードを作成していますか?

Androidこれは多くの低レベルの数値計算を行うC.コードを持っています。使用する設定(たとえば、Android.mkやApplication.mkの場合)ファイルを知りたい生成されたコードは現在のすべてのAndroidデバイスで実行されますが、特定のチップセットの最適化も利用します。使用する適切なデフォルトのAndroid.mkおよびApplication.mk設定を探しています#ifdefブランチでCコードを散らかすことを避けたい。

たとえば、ARMv7には浮動小数点命令があり、一部のARMv7チップはNEON命令をサポートし、デフォルトARMはこれらのどちらもサポートしません。ビルドできるようにフラグを設定することはできますか? NEONを備えたARMv7、NEONを備えないARMv7、およびデフォルトARM build?後者の2つを実行する方法を知っていますが、3つすべてではありません。現在のデフォルトは最も安全な設定であり、他のオプションが持つリスクです。

GCC固有の最適化のために、次のフラグを使用しています。

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

これら3つすべてをチェックして、コードを高速化しました。追加できる他の一般的なものはありますか?

もう1つのヒントは、Android.mkに「LOCAL_ARM_MODE:= arm」を追加して、新しいアームチップの速度を上げることです(ただし、これが何をするのか、古いチップで何が起こるのか正確に混乱しています)。

53
rbcc

ARMプロセッサには、「ARM」と「Thumb」という2つの一般的な命令セットがサポートされています。両方に異なるフレーバーがありますが、ARM命令はそれぞれ32ビットであり、Thumb命令は16ビットです。2つの主な違いは、ARM命令がたとえば、単一のARM命令は、2番目のレジスタで左シフトを実行しながら、1つのレジスタを別のレジスタに追加できます。Thumbでは、1つの命令シフトを実行する必要があり、2番目の命令が追加を実行します。

ARM命令の性能は2倍ではありませんが、場合によってはより高速になります。これは、手巻きのARMアセンブリで特に当てはまります。これは、「無料のシフト」を最大限に活用するための斬新な方法で調整できます。Thumb命令には、サイズだけでなく利点もあります。バッテリーの消耗が少なくなります。

とにかく、これはLOCAL_ARM_MODEが行うことです。つまり、Thumb命令ではなくARM命令としてコードをコンパイルすることを意味します。Thumbへのコンパイルは、より小さなバイナリとコンパイラは、ARMが提供できる余分な「オーフ」を常に利用できるとは限らないため、最終的には同じ数のとにかく指示。

ARMまたはThumbにコンパイルされたC/C++コードから見た結果は同じです( コンパイラのバグ を除く)。

これは、それ自体で、新しいものと古いものの間で互換性がありますARMすべてのプロセッサAndroid現在利用可能な携帯電話。これは、デフォルトでNDKが「Application Binary Interface ARMv5TE命令セットをサポートするARMベースのCPU用。このABIは「armeabi」と呼ばれ、_APP_ABI := armeabi_を指定することでApplication.mkで明示的に設定できます。

新しいプロセッサは_armeabi-v7a_として知られるAndroid固有のABIもサポートします。これはarmeabiを拡張して Thumb-2命令セット とVFPv3-D16というハードウェア浮動小数点命令セットを追加します。 armeabi-v7a互換CPUは、オプションでNEON命令セットをサポートすることもできます。NEON命令セットは、実行時に確認し、使用可能と使用不可のコードパスを提供する必要があります。これを行うNDK/samplesディレクトリに例があります(hello-neon)。内部では、Thumb-2はより多くの「ARMに似ています」という点で、その命令は1つの命令でより多くの処理を実行できる一方で、スペースをあまり占有しないという利点があります。

Armeabiライブラリとarmeabi-v7aライブラリの両方を含む「脂肪バイナリ」をコンパイルするには、次をApplication.mkに追加します。

_APP_ABI := armeabi armeabi-v7a
_

.apkファイルがインストールされると、Androidパッケージマネージャーはデバイスに最適なライブラリをインストールします。したがって、古いプラットフォームではarmeabiライブラリをインストールし、新しいデバイスではarmeabi-v7aをインストールします。

実行時にCPU機能をテストする場合は、NDK関数uint64_t Android_getCpuFeatures()を使用して、プロセッサでサポートされている機能を取得できます。これは、v7aプロセッサでは_Android_CPU_ARM_FEATURE_ARMv7_のビットフラグ、ハードウェア浮動小数点がサポートされている場合は_Android_CPU_ARM_FEATURE_VFPv3_、高度なSIMD命令がサポートされている場合は_Android_CPU_ARM_FEATURE_NEON_を返します。 ARM VFPv3なしではNEONを使用できません。

要約すると、デフォルトでは、プログラムは最も互換性があります。 LOCAL_ARM_MODEを使用すると、ARM命令を使用するため、バッテリー寿命を犠牲にして少し速くなります。デフォルトのセットアップと同じ互換性があります。_APP_ABI := armeabi armeabi-v7a_新しいデバイスのパフォーマンスは向上し、古いデバイスとの互換性は維持されますが、.apkファイルは大きくなります(2つのライブラリがあるため)NEON命令を使用するには、機能を検出する特別なコードを記述する必要があります実行時のCPUの使用率。これはarmeabi-v7aを実行できる新しいデバイスにのみ適用されます。

112
richq

追加したいだけでいい

APP_ABI := all

これにより、4つのバイナリ、armv5、armv7、x86、およびmipsがコンパイルされます。

あなたはndkの新しいバージョンが必要な場合があります

23
user1159819