Dalvik と Android ツールチェーンからどのような最適化が期待できますか? 質問する

Dalvik と Android ツールチェーンからどのような最適化が期待できますか? 質問する

私は高性能な Android アプリケーション (ゲーム) に取り組んでいます。まずは読みやすさを重視してコードを記述しようとしていますが、常に頭の中で裏側で何が起こっているかを把握しておきたいと思っています。C++ では、コンパイラが何をしてくれるか、何をしてくれないかについて、かなり正確な直感を養うことができました。Java/Android でも同じことをやろうとしています。

そこでこの質問です。Web 上でこのトピックに関する情報はほとんど見つかりませんでした。Java コンパイラ、Dalvik コンバータ (dx)、および/または JITter (Android 2.2 以降) は、次のような最適化を実行しますか?

  • メソッドのインライン化。どのような条件下では、privateメソッドは常に安全にインライン化できます。これは実行されますか?public finalメソッドはどうですか? 他のクラスのオブジェクトのメソッドですか?staticメソッドですか? オブジェクトのランタイム型がコンパイラによって簡単に推測できる場合はどうなりますか? 可能な場合は常にメソッドをfinalまたはとして宣言する必要がありますかstatic?

  • 共通部分式の削除。たとえば、someObject.someField2 回アクセスする場合、検索は 1 回だけ実行されますか? ゲッターの呼び出しの場合はどうなりますか? 算術式を 2 回使用した場合、評価は 1 回だけ行われますか? 値が変更されないことがわかっている式の結果をループの上限として使用する場合はどうなりますかfor?

  • 配列検索での境界チェック。ツールチェーンは、典型的なループのような特定の状況でこれを排除しますかfor?

  • 値のインライン化。一部へのアクセスはpublic static final int常にインライン化されますか? 別のクラスにある場合でも? 別のパッケージにある場合でも?

  • 分岐予測。これはどの程度大きな問題なのでしょうか? 分岐は一般的な Android デバイスのパフォーマンスに大きな影響を与えますか?

  • 簡単な算術演算。?someInt * 2に置き換えられます。someInt << 1

などなど…

ベストアンサー1

Google の JIT に取り組んでいるエンジニアの 1 人、Ben です。Bill と私がこのプロジェクトに着手したときの目標は、リソース競合 (メモリ フットプリント、コンパイラ スレッドによる CPU ハイジャックなど) への影響を最小限に抑えながら、ローエンド デバイスでも実行できる、機能する JIT をできるだけ早く提供することでした。そのため、非常に原始的なトレース ベースのモデルを使用しました。つまり、JIT コンパイラに渡されるコンパイル エンティティは基本ブロックであり、1 つの命令ほど短い場合もあります。このようなトレースは、実行時にチェーンと呼ばれる手法によってまとめられるため、インタープリタとコード キャッシュの検索が頻繁に呼び出されることはありません。ある程度、高速化の主な要因は、頻繁に実行されるコード パスで繰り返されるインタープリタ解析のオーバーヘッドを排除することにあります。

そうは言っても、Froyo JIT で実装されたローカル最適化はかなりあります。

  • レジスタ割り当て (JIT は Thumb コードを生成するため、v5te ターゲットの場合は 8 レジスタ / v7 の場合は 16 レジスタ)
  • スケジューリング (例: Dalvik レジスタの冗長な ld/st の削除、ロード ホイスト、ストア シンク)
  • 冗長な null チェックの除去 (基本ブロック内にそのような冗長性が見つかった場合)。
  • 単純なカウント ループ (つまり、ループ本体にサイド出口がない) のループ形成と最適化。このようなループでは、拡張誘導変数に基づく配列アクセスが最適化され、ループのプロローグでのみ null および範囲チェックが実行されます。
  • 実行時に動的パッチを適用する仮想呼び出しサイトごとに 1 つのエントリ インライン キャッシュ。
  • mul/div のリテラルオペランドの電力削減などのピープホール最適化。

Gingerbread では、ゲッター/セッターにシンプルなインライン化を追加しました。基盤となる JIT フロントエンドは依然としてシンプルなトレース ベースであるため、呼び出し先に分岐がある場合はインライン化されません。ただし、インライン キャッシュ メカニズムが実装されているため、仮想ゲッター/セッターは問題なくインライン化できます。

現在、コンパイラがコード分析と最適化のためにより大きなウィンドウを持つように、単純なトレースを超えてコンパイル範囲を拡大する作業を行っています。お楽しみに。

おすすめ記事