Android* アプリケーション向けにインテル® C++ コンパイラーの高度な機能を利用する

同カテゴリーの次の記事

インテル® C++ コンパイラーと GNU* gcc を使用して x86 および ARM* APK を生成する

この記事は、インテル® Developer Zone に公開されている「Using Advanced Intel® C++ Compiler Features for Android* Applications」の参考訳です。


目次

Android 上でアプリケーションをマルチスレッド化するため、インテル® Cilk™ Plus ランタイムを使用する

インテル® Cilk™ Plus は、マルチコア・プロセッサーでプログラムのパフォーマンスを向上させ、迅速、容易、かつ信頼性の高い方法を提供する、C および C++ の言語拡張です。インテル® Cilk™ Plus の 3 つのキーワードは、並列プログラミング用の単純で非常に強力なモデルを提供します。その一方で、ランタイム・ライブラリーとテンプレート・ライブラリーは、並列アプリケーションの実行向けにきめ細やかにチューニングされた環境を提供します。

アプリケーションをマルチスレッド化するためインテル® Cilk™ Plus を使用すると、Cilk ランタイム・ライブラリー(libcilkrts.so) にリンクする必要があります。

インテル® C++ コンパイラーを NDK ツール (ndk-build) と統合して開発を行う。

NDK ビルドシステムは、C で記述された C モジュールに C++ ライブラリーをリンクしないため、コンパイラーはリンク時に Cilk Plus ライブラリーを検出できないため、リンクエラーとなる可能性があります。

  1.  NDK ビルドシステムで C++ のリンクを有効にするには、空の C++ ソースファイルを追加します。
  2.  Application.mk ファイルに C++ との互換性実装を指定します。
    • Ÿ   ‘APP_STL:=stlport_shared’ もしくは
    • Ÿ   ‘APP_STL:=gnustl_static’ または
    • Ÿ   ‘APP_STL:=gnustl_shared’
  3. 以下の “JNI 呼び出しの用意” の節で説明するように Java コードを修正します。

NDK ビルドシステム (ndk-build) を利用せずインテル® C++ コンパイラーを単独で使用して開発を行う。

C++ コードから成る開発環境は、明示的に GNU_STL ライブラリーもしくは stlport ライブラリーにリンクする必要があります。

次の手順に従ってください:

  1. NDK に含まれる C++ の実装をコンパイルしてリンクするには、次のオプションを指定します:
    • Ÿ   コンパイル・オプション:
      -I$ANDROID_GNU_LIBSTDCPP/include
      -I$ANDROID_GNU_LIBSTDCPP/libs/x86/include
    • Ÿ   リンクオプション(gnustl_shared):
      -L$ANDROID_GNU_LIBSTDCPP/libs/x86 -lgnustl_shared -lsupc++
    • Ÿ   リンクオプション(gnustl_static):
      -L$ANDROID_GNU_LIBSTDCPP/libs/x86 -lgnustl_static -lsupc++

    ANDROID_GNU_LIBSTDCPP には、ANDROID_GNU_LIBSTDCPP=$NDK/sources/cxx-stl/gnu-libstdc++/4.6 を想定します。 4.6 は、ANDROID_GNU_X86_TOOLCHAIN が示す GCC のバージョンで置き換えます。

    例えば、ANDROID_GNU_X86_TOOLCHAIN が $NDK/toolchains/x86-4.8/prebuilt/linux-x86 を指していれば、4.6 は 4.8 に置き換えます。

    インテル® Cilk™ Plus を使用する場合、さらに libcilkrts.so もリンクします。このライブラリーは、 /compiler/lib/ia32/gnustl ディレクトリーにあります。

  2.  stlport_shared C++ ライブラリー(最新の NDK-r9 で必要)が使用されている場合、次のオプションを追加します:

    • Ÿ   コンパイル・オプション:
      -I$ANDROID_STLPORT_LIBSTDCPP/stlport

    • Ÿ   リンクオプション:
      -L$ANDROID_STLPORT_LIBSTDCPP/libs/x86 -lstlport_shared
    • ANDROID_STLPORT_LIBSTDCPP は、ANDROID_STLPORT_LIBSTDCPP=$NDK/sources/cxx-stl/stlport に設定します。

      インテル® Cilk™ Plus を使用する場合、対応する libcilkrts.so ライブラリー は、/compiler/lib/ia32/stlport ディレクトリーにあります。

JNI 呼び出しの用意

インテル® Cilk™ Plus を使用するには、JNI 呼び出しが必要です。 ‘libcilkrts.so’ ライブラリーは、次の API 呼び出しによって Java コードから呼び出す必要があります:

アプリケーションが動的な C++ の実装に依存している場合、libcilkrts.so 以外の必要なライブラリーをロードしなければいけません。

System.loadLibrary("gnustl_shared");
System.loadLibrary("cilkrts");

もしくは、
System.loadLibrary("stlport_shared");
System.loadLibrary("cilkrts");

Androif* OS アプリケーションのパフォーマンスを改善するため PGO を使用する。

プロファイルに基づく最適化 (PGO) では、命令キャッシュの問題を軽減させるコードの再構成、コードサイズの減少、分岐予測ミスの減少などによりアプリケーション・パフォーマンスの向上を図ることができます。PGO を行うと、アプリケーションで最も頻繁に実行される領域に関する情報がコンパイラーに伝えられます。この領域を知ることで、コンパイラーは、より慎重かつ明確にアプリケーションの最適化を行います。

Android 上で PGO を利用すると、他のオペレーティング・システム比べ追加の手順が必要です。

  1. jni/Android.mk ファイルの C フラグに次のオプションを追加します:
    LOCAL_CFLAGS:= -prof-gen -prof-dir /sdcard
  2. アプリケーションが PGO の出力を sdcard フォルダーに書き込めるよう、WRITE_EXTERNAL_STORAGE パーミッションを追加します。AndroidManifest.xml ファイルに次のコードを追加します。
    <uses-permission android:name=”android.permission.WRITE_EXTERNAL_STORAGE” \>
  3.  プロファイル・データが書き込まれていることを確認します。
    プロファイル・データは、デフォルト・モードではアプリケーションが exit した時にのみ書き込まれます。通常 Android* 上のアプリケーションは exit しません。アプリケーションに exit を強制するかこの問題の解決策を適用するには、次の選択肢があります。

    a. 選択肢 1:

    JAVA コードから exit を呼び出す。

    System.exit(0);

    b. 選択肢 2:

    ネイティブコードから明示的に PGO データの書き出しを行う。

    #include <pgouser.h>
    _PGOPTI_Prof_Dump_All();

    c.  選択肢 3:

    アプリケーションの実行中にパフォーマンス・データが sdcard に書き込まれるよう、環境変数を設定する。全てのアプリケーションに環境変数が適用されるように、 Android イメージの init.rc ファイルにそれらを追加します。

    export INTEL_PROF_DUMP_INTERVAL   5000
    export INTEL_PROF_DUMP_CUMULATIVE   1

    注:

    INTEL_PROF_DUMP_INTERVAL 値はマイクロ秒で測定され、INT_MAX を超えることはできません。

  4. ターゲットで生成された dyn ファイルをホストのソースコードと同じディレクトリーへコピーします。

    adb   pull ...
  5. Android.mk ファイルの C フラグを生成された dyn ファイルを使用するよう変更します。-prof-dir 引数を使用して異なる場所の dyn ファイルを参照できます。

    LOCAL_CFLAGS := -prof-use

    Linux*、Windows*、そして OS X* 上でインテル® C++ コンパイラーの PGO を使用してアプリケーションを最適化する際の詳細情報は、パッケージに含まれるインテル® C++ コンパイラー XE 14.0 のユーザーおよびリファレンスガイドのプロファイル・ガイド最適化の節を参照してください。

    コンパイラーの最適化に関する詳細は、最適化に関する注意事項を参照してください。

関連記事