Upgrade to Pro — share decks privately, control downloads, hide ads and more …

進化するART

kmt-t
April 25, 2015

 進化するART

kmt-t

April 25, 2015
Tweet

More Decks by kmt-t

Other Decks in Programming

Transcript

  1. 1 自己紹介 • ハンドルネーム – @kmt_t • 職業 – 業務系プログラマ

    – 元組み込み系 • 専門分野 – 画像処理、ファイルシステム、仮想マシン – 最近は自然言語処理、ディープラーニング
  2. 今日話す内容 • ARTの概要 • ARTの実行ファイル • ARTのコンパイラ • 今回解説するのはバージョン5.1.0_r1.0 4

    注意! コードがかなり頻繁に変わるので 将来的に正しい保証はありません
  3. ARTとは何か? • (ART = Android RunTime) • ランタイムとは – アプリケーション実行環境

    – コアライブラリ • Androidのランタイムとは – Dalvikバイトコードの実行環境 – KitKatまではDalvik – LolipopからはART 6
  4. ARTの特徴 • コードの変更点 – Dalvikから完全書き換え – プログラミングはC言語からC++11 • アーキテクチャの変更点 –

    JITコンパイラからAOTコンパイラに • バイトコードを機械語にコンパイル • AOTコンパイラでアプリケーションインストール 時にコンパイルするように変更 – ガベージコレクションが改善 – 64bitCPU対応 7
  5. ARTの実行ファイル • OATファイル – AOTコンパイラが出力する実行ファイル – 機械語はOATファイルに保存 • DEXファイル –

    OATファイルに埋め込まれる – メタデータはDEXファイルをそのまま使用 – 「Androidの仮想マシンDalvik編」参照 10
  6. OATファイルの概要 • ELF形式 – Linuxでは一般的に使われている形式 – OATファイルは共有ライブラリ • リンカとローダはART独自 –

    リンカ、ローダとは? – メモリへ展開 – アドレスの再配置 – シンボルの解決 – 詳細は「Linkers & Loaders」参照 11
  7. ELFの概要 • 以下のブロックに分割 – ELFヘッダ – プログラムヘッダ • セグメント情報 –

    セグメント – セクション – セクションヘッダ • セクション情報 • セグメントとセクションは同じ領域を別 の論理単位に分割 12 ELFヘッダ プログラムヘッダ セグメント または セクション セクションヘッダ
  8. OATファイルをobjdumpする 13 # arm-linux-androideabi-objdump -h ./boot.oat ./boot.oat: file format elf32-littlearm

    Sections: Idx Name Size VMA LMA File off Algn 0 .dynsym 00000040 709780f4 709780f4 000000f4 2**2 CONTENTS, ALLOC, LOAD, READONLY, DATA 1 .dynstr 00000026 70978134 70978134 00000134 2**0 CONTENTS, ALLOC, LOAD, READONLY, DATA 2 .hash 00000020 7097815c 7097815c 0000015c 2**2 CONTENTS, ALLOC, LOAD, READONLY, DATA 3 .rodata 01a50000 70979000 70979000 00001000 2**12 CONTENTS, ALLOC, LOAD, READONLY, DATA ※ ART独自のデータ含む 4 .text 01499d80 723c9000 723c9000 01a51000 2**12 CONTENTS, ALLOC, LOAD, READONLY, CODE 5 .dynamic 00000038 73863000 73863000 02eeb000 2**12 CONTENTS, ALLOC, LOAD, READONLY, DATA 6 .oat_patches 001af258 00000000 00000000 02eeb038 2**3 CONTENTS, READONLY ※ ART独自のセクション
  9. .rodataセクション • DEXファイルとガイド情報 14 アイテム名 内容 OatHeader .rodataに保存されているデータのヘッダ OatDexFile DEXファイルをmmapするファイル名の配列

    Dex DEXファイルの配列 (DEXファイルそのもの) OatClass クラスに紐付けられたコンパイル済みメソッドの位置 GcMap ガベージコレクションのガイド情報 VmapTable 仮想マシンのレジスタに格納されている値の型 MappingTable CPUと仮想マシンのプログラムカウンタの対応表
  10. .oat_patchesセクション • イメージファイルの再配置情報 • イメージファイルとは? – イメージファイルはアプリケーション起動時 にImageSpaceヒープにロードされる – イメージファイルはロードされるたびにアド

    レスを変更するため、再配置が必要 • ImageSpaceヒープに含まれるデータ – 定数文字列、クラスメタデータ、メソッドメ タデータのJavaオブジェクトインスタンス • 通常のELFファイルには含まれない 15
  11. その他セクション (一般的な使い方) • .dynsimセクション – 動的リンクのシンボルテーブル • .dynstrセクション – .dynsymのシンボル文字列テーブル

    • .hashセクション – シンボル検索用のハッシュテーブル – 一般的にはリンカ、ローダ用 – リンカ、ローダが独自実装であるARTでは使用しない • .dynamic – 動的リンクシンボル検索用のハッシュテーブル – 一般的にはリンカ、ローダ用 – リンカ、ローダが独自実装であるARTでは使用しない 17
  12. Quickコンパイラの特徴 • Quickコンパイラは – DalvikのJITコンパイラベース – DalvikのJITコンパイラを先に理解する – 「Androidの仮想マシン Dalvik編」参照

    • ARTが速くなったのは何故? – コンパイラ方式が変更、だけではない! – ランタイム全体の改善 – メモリアロケータの高速化 – ガベージコレクションの高速化 21
  13. Quickコンパイラのアーキテクチャ 22 バイトコード MIR 最適化 LIR 機械語 •バイトコードに近い表現 •基本ブロックに分割 •レジスタをSSA形式に変換

    •制御フローダイアグラム、支配木に変換 •ほとんどの最適化はここでやる •機械語に近い表現 •ただし機械語独立 •コンパイル済みコード
  14. 制御フローダイアグラム (CFD) • 基本ブロックの分岐をグ ラフ化したもの • コードやレジスタの 生死の判定で使用 24 基本

    ブロックM 基本 ブロックL 基本 ブロックN 基本 ブロックO 基本 ブロックP If true If false
  15. 支配木 • ある基本ブロックの前に 必ず通る基本ブロックの ことを「支配する」 • SSAの最適化で使用 • 「MはNを支配する」 25

    基本 ブロックM 基本 ブロックL 基本 ブロックN 基本 ブロックO 基本 ブロックP If true If false
  16. 最適化一覧 (1/2) 手法 DX Dalvik ART エスケープ解析 (配列オブジェクトの消去) ◦ ×

    × Pruned-SSA ◦ ◦ ◦ 定数伝播 ◦ ◦ ◦ 定数畳み込み ◦ × × 定数集約 (同じ定数のロードを一カ所に) ◦ × ◦ 基本帰納変数による計算の簡略化 × ◦ × ループ不変式の移動 × ◦ ◦ インライン展開 × ◦ ◦ 死んだコードの除去 ◦ ◦ ◦ 無駄な仮想マシンレジスタ複製の除去 ◦ × ◦ リテラルの命令埋め込み ◦ × × 26
  17. 最適化一覧 (2/2) 手法 DX Dalvik ART 無駄なNULLチェックの除去 × × ◦

    無駄なクラス初期化チェックの除去 × × ◦ 32bit整数以外の比較とジャンプ命令の結合 × × ◦ フィールドオフセットの命令埋め込み × × ◦ 反仮想化 (仮想メソッドの仮想化除去) × × ◦ 基本ブロックの並びの最適化 × × ◦ 無駄な例外ハンドラの除去 × × ◦ 無駄なメモリロードの抑止 × ◦ ◦ 仮想マシンレジスタのCPUレジスタへの昇格 × × ◦ 無駄なCPUレジスタ複製の抑止 × × ◦ CPUレジスタ割り当ての重み付け (移動コストや 使用頻度の高いCPUレジスタは破棄されない) × × ◦ 27
  18. ARTのコンパイラの欠点 • 多くの最適化をMIRでやる – CPUアーキテクチャ依存の機械語レベルの最 適化は皆無 – 機械語レベルの最適化はCPUアーキテクチャ に依存しており、開発工数がかかる –

    DalvikではLIRがCPUアーキテクチャ依存だっ たがARTは非依存 – DalvikではIntelがx86向けの機械語の最適化 コードをコントリビュートしていた 29
  19. まとめ • 実行ファイル – ELF形式である – ART独自のデータが含まれる – ART独自のリンカとローダ •

    コンパイラ – DalvikのJITコンパイラベース – LLVMはつかっていない – CPUアーキテクチャ依存の最適化は若干弱い • コード変更が頻繁であり「進化してる」 30
  20. まとめ • 実行ファイル – ELF形式である – ART独自のデータが含まれる – ART独自のリンカとローダ •

    コンパイラ – DalvikのJITコンパイラベース – LLVMはつかっていない – CPUアーキテクチャ依存の最適化は若干弱い • コード変更が頻繁であり「進化してる」 31 マスターブランチとkitkat-mr1-releaseブランチの差分 $ git diff 21b2216e4aa3756b5f96a587e99ac4fd0b16b844 | wc -l 539703