2011-02-06 6 views
67

私は高性能なAndroidアプリケーション(ゲーム)を開発していますが、最初に読みやすさをコード化しようとしていますが、私は心の中に何が起こっているのかを後で把握したいと思います。 C++では、私はコンパイラが私にとって何をしてくれないかについてかなり良い直感を築きました。私はJava/Androidでも同じことをしようとしています。DalvikとAndroidツールチェーンの最適化について教えてください。

したがって、この質問。私はこの話題についてウェブ上でほとんど見つけることができませんでした。 JavaコンパイラであるDalvikコンバータ(dx)やJITter(Android 2.2以降)は、次のような最適化を実行しますか?

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

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

  • 境界の検索を確認します。ツールチェーンは、特定の条件(ループの典型的なforループのような)でこれを排除しますか?

  • 値インライン化。 public static final intへのアクセスは常にインライン化されますか?たとえ彼らが別のクラスにいても?彼らが別のパッケージに入っていても?

  • 分岐予測。この問題はどれくらい大きな問題ですか?典型的なAndroid搭載デバイスでは、ブランチングのパフォーマンスが低下しますか?

  • 単純な算術。は、someInt << 1に置き換えられますか?someInt * 2someInt << 1に置き換えられますか?

エトセトラ...

+5

これは役に立つかもしれません:http://developer.android.com/guide/practices/design/performance.html – pablochan

+2

これらは便利かもしれません:http://www.netmite.com/android/mydroid/dalvik/ docs/dexopt.html、http://www.taranfx.com/android-internals-jit-froyo、およびプレゼンテーションのpdfバージョン:http://www.android-app-developer.co.uk/android- app-development-docs/android-jit-compiler-androids-dalvik-vm.pdf – Lior

+0

@pablochan:私の枕の下にいたのですが、感謝します:) @Lior:良い参考書、 ! – Thomas

答えて

102

これはJIT @ Googleで働くエンジニアの1人です。 Billと私がこのプロジェクトを開始したとき、目標はリソースの競合(例えば、メモリフットプリント、CPUがコンパイラスレッドによってハイジャックされるなど)に与える影響を最小限に抑えてできるだけ早く実用的なJITを提供し、ローエンドのデバイスよくしたがって、我々は非常に基本的なトレースベースのモデルを使用しました。つまり、JITコンパイラに渡されるコンパイルエンティティは基本ブロックです。単一の命令と同じくらい短いこともあります。このようなトレースは、インタプリタとコードキャッシュの検索が頻繁に呼び出されないように、チェーンと呼ばれる手法によって実行時に一緒に縫い合わせられます。ある程度、高速化の主な原因は、頻繁に実行されるコードパス上の繰り返しインタープリタのパーズオーバーヘッドを排除することにあります。我々はフローズンヨーグルトのJITで実装かなりの数のローカル最適化を持っている

言っ:

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

ジンジャーブレッドではゲッター/セッター用の単純なインラインを追加しました。根底にあるJITフロントエンドは依然として単純なトレースベースなので、呼び出し先がそこに分岐を持っていれば、それはインライン化されません。しかしインラインキャッシュメカニズムは、仮想ゲッター/セッターが問題なくインライン化できるように実装されています。

私たちは現在、単純なトレースを超えてコンパイルスコープを拡大しているため、コンパイラのコード解析と最適化のためのウィンドウが大きくなっています。乞うご期待。

+1

共有ありがとう! –

+11

あなたは特にこれに答えるためにサインアップしましたか?ありがとうございました!オペレーターがジンジャーブレッドを展開するにはとても遅いのは残念です。私が思う少なくとももう1年は、これらの最適化には期待できません。これはすべていいものですが、私はコンパイラ作家ではないので、実際にそれをどのように適用するのが見苦しいですか。特に:... – Thomas

+2

(1)ループの上限は、最終的ではない変数(フィールドなど)に依存する場合、または上限を最終ローカル変数に格納する必要がある場合にも行われますか? (2)繰り返しアクセスされるすべてのフィールドに同じ質問があります。 (3)可能な限り私の方法は「最終的に」宣言すべきですか?それとも、それでも仮想コールサイトとしてカウントされますか? (4)インライン展開は一般的にJITレベルでは行われていませんが、コンパイラやDXツールがそれを行うかどうかは分かりません。 – Thomas

10

私は私の答えはあなたの質問のすべてに答えていないだろうことを確信しているが、私はそれも1に答えるならば、それは勝利だと思います。

あなたはその件について深い知識を持っているようですが、あなたが望むものが分かっているので、次のことをしたいかもしれません。調査したい側面を含むサンプルアプリケーションを作成します。

入手したAPKには、APK Toolでアクセスしてください。私たちが知っているように、あなたが意図していることを行うためのコードをリバースエンジニアリングすることは、まったく問題ありません。

APKツールはリソースを抽出してデコードし、.dexファイルを.smaliファイルにリバースエンジニアリングします。ファイル.smaliの読み取り方法とその制限について詳しくは、smaliプロジェクトを参照してください。

これもあなたの質問のすべてに答えるつもりはありませんが、それは良いスタートになるかもしれません。

+1

良い答え、ありがとう。その調査のラインは、主に時間がかかるので、私にはまだ起こっていませんでした。これは、Javaコンパイラとdxが何をしているかを少なくとも示しますが、JITterの影響は不明です。私が好奇心を感じ、この道を行くと、私はここに結果を掲載することになります。 – Thomas

+0

はい、してください。私は自分自身の結果に非常に興味があります。 –

+1

javacはいくつかの最適化を行いますが、劇的なものはありません。 "dx"は入力を忠実に変換します。 Benが指摘したように、これらのことが真実でないと、デバッガでは苦労します。実際の例については、http://groups.google.com/group/android-platform/browse_thread/thread/e4749164474fb429/93901e2e43a657c8(特に、「dx」は、 -g "をjavacに渡します)。 ProGuardの最適化についても調べる必要があります。 – fadden

5

まず、私はdalvikの専門家ではなく、私の反応のいくつかは間違っていると言ってこれを序文にします。しかし、私はdalvikのJITコードを掘り下げました。私はdalvikが実行するバイトコードをよく知っています。

  1. メソッドインライン化 - 私が知る限り、これは起こりません。私はそれがバイトコードレベルでは決して起こらないことはほぼ肯定的であり、現在はJITレベルで起こっているとは思わない。

  2. 一般的な部分式の削除 - これは、最終的でない変数/フィールドを使用しない部分式に対してのみ行われると思います。それでも起こったら、私は完全に肯定的ではない。それが済んだら、私はそれがバイトコードレベル、おそらくJITレベルで行われることを期待します。配列検索にチェックを

  3. 境界 - 見当もつかない

  4. 値のインライン化 - 私の知る限りでは、はい - 彼らはこれらのシナリオのすべてにインライン化されます。

  5. 分岐予測 - わからない

  6. 単純な算術 - ない限り、私はまた

を知っているように、私はあなたにアプローチの別の道を言及したいと思います - DXとのDalvikがありますどちらもオープンソースなので、あなたが好きなものをすべて見つけ出すことができます。彼らは明らかに小さなコードベースではありませんので、そのレベルで彼らを掘り下げる努力がかなり必要です

+0

これは何かが進むならば、私は自分のメソッドを手でインライン化し、サブ表現の結果をキャッシュするのにうまくやってきました。ありがとう! – Thomas

関連する問題