2014 dart flight school in tokyo
DESCRIPTION
2014 dart flight school in Tokyo dart vm overviewTRANSCRIPT
Dart VMの紹介
Outline Dart VM 1.1 Dart2js 1.1 Dart VMの特長
2014/02/22 Dart Flight School 2014 Tokyo
nothingcosmos <[email protected]>
自己紹介
Twitter:nothingcosmos 名前 :坂頂佑樹 所属 : 趣味 :OSSのコードを弄る Blog:http://nothingcosmos.blog52.fc2.com/ Dart VM Advent Calender 2012
http://nothingcosmos.github.io/DartVM/index.html Dart VMのソースコードリーディング
Dart VMのゴール
Dart VM 1.1
Dart VMとは、 JVM、 V8みたいなもの。
Dartのコードを JITコンパイルして高速に実行可能
対応アーキテクチャは、 x86/x64/arm/mips
対応OSは、 Linux/Windows/MacOS/Android
ここ半年で ARM + Android対応完了
V8より高速だが、 2倍はいかない。
一時期はほぼ 2倍差をつけたけど、その後
V8が怒濤の追い込み。。
今は V8の 40~ 50%速いくらい
Computer Language Benchmark Games x86 Ubuntu™ Intel® Q6600® one core
Dart / Java7
JavaなのにGMP使ってるBigInteger同士だと等速
Dartは簡易 regex engineのみブラウザ搭載時に
Irregexpに置き換え
IOが List<int>結構遅い
ここ 1年くらいの Dart VM
2013/01 arm mipsの skeletonを追加。 Typed arrayの高速な実装を追加
2013/02 mixinを追加開始
2013/03 Field type feedback最適化を追加し、全体的に 30%程度性能向上
2013/04 ARMとMIPSの simulator上のコンパイル、動作確認
2013/06 On-Stack Replacementの追加
2013/07 NEON対応。Mirrorの高速化
2013/08 Profile Guided Code Positioningの追加
2013/09 ARM対応ほぼ完了。 vm serviceを追加開始
2013/10 Constant Blindingの追加。
2013/11 Dart 1.0リリース
2013/12 Field操作のmutable化
2014/01 Dart 1.1リリース
dart2js 1.1
Dartで開発されている、 Dartから JavaScriptへの変換
Dart VMがないブラウザでも動作可能
高速化中、手書きの JavaScript V8と等速、ちょい速いくらい。
Dart 1.0より、ベンチマークの Richardが 25%アップ。
http://news.dartlang.org/2014/01/dart-11-features-up-to-25-faster.html
いろいろと最適化を追加して高速化と出力 jsの圧縮を頑張っている
ベンチマークはOctane やDromaeoや Box2Dっぽい。
Dart2js Tracer Benchmarkhttps://www.dartlang.org/performance/
SsaLoadElimination
type_graph_inferrer
Dart VMの特長ここから VMの雑学
JITコンパイル
Dart VM Architectureと Isolate
Snapshotと高速起動
Message passingと Event Driven
Optional Typing & Generics & Checked Mode
Dartium
Dart VMと JITコンパイル (1)
EntrypointであるmainscriptをSingleThreadingで
JITコンパイルしてから実行する
インタプリタなし、 2段階の JITコンパイル
IRHydraがわかりやすい。
http://mrale.ph/irhydra/2/#demo-4
関数呼び出し fiboを見つけるfiboはまだコンパイルしていないため、
fibo関数を JITコンパイルする
Dart VMと JITコンパイル (2)
fibo関数を JITコンパイルした後、fibo関数の実行に戻る
最初の JITコンパイルは、
どんな型でも動くように汎用コンパイル
型情報の収集を埋込
fibo関数を再帰的に実行コンパイル済みの汎用コードを実行する
Dart VMと JITコンパイル (3)
fibo関数を何度も実行すると、fibo関数の最適化 JITコンパイルが走る。
汎用的な fiboから、最適化した fiboに置き換え
何度も実行される関数は、最適化 JITコンパイル
収集した型情報を利用し、
型を特殊化してコンパイル、高速に実行可能
Heapが足りなくなったら、全体の動作を止めて、GCを実行し、
heapを確保する。
runtime/libruntime/bin
BOOTSTRAP_NATIVES
Dart VM Architecture
runtime/platform
OS(Linux, Windows,MacOS, Android)
ISA(arch)ia32/x64/arm/mips
runtime/vm
runtime/include
sdk/lib
IO_NATIVES
runtime/vm/os
patch_class
runtime/lib/*.ccruntime/bin/*.cc
sdk/lib/io
I/OやNetworkを非同期に実行
Dartの世界Debuggerで追える境界
VMの境界Native Extensionsシンボルを定義
VMが担当する計算やリソース管理
Dart
C++/Asm
OS/Kernel
NativeSymbol
Dart VM Isolate
isolate
OSの Process
heap Dart_Apiinclude
port_map thread_pool
GC
objectpool/code
compiler
intrinsifier/runtime_entry
runtimestubs
dartcontext
VMの共有リソース
Isolate単位に独立Single Threadingで
動作する
BOOTSTRAP_NATIVESDartレイヤからC++への binding/Native Extentions
Isolate横断
JITCompilerのみインタプリタ無し
MessagePassingはport経由
IsolateごとにGCと heap
Isolate Spawn
isolate
OSの Process
heap Dart_Apiinclude
port_map thread_pool
GC
objectpool/code
compiler
intrinsifier/runtime_entry
runtimestubs
dartcontext
isolate
ThreadThread
heapGC
objectpool/code
compiler
dartcontext
runtimestubs Spawnした
Isolate
isolate間は port経由でmessage passing
Lockは不要独立して実行
共有リソースでは Lockするが、非常に少ない。
ここより上のDartのレイヤーにはLockが存在しない
Dart VMの特長ここから VMの雑学
JITコンパイル
Dart VM Architectureと Isolate
Snapshotと高速起動
Message passingと Event Driven
Optional Typing & Generics & Checked Mode
Dartium
Dart Snapshot
Dart VMの objectの serialize/deserialize機能圧縮率と速度優先
アーキテクチャ非互換 (x86-x64-ARM間の相互変換は不可能 )
起動の高速化
MessagePassingの際の serialize/deserializeにも使用する。
serialize した objectを port経由で送受信する。
自分の作ったライブラリもあらかじめ snapshotできる。
大体 JSONと同じだけど、追加で VMの内部 objectも対象。
VM起動の高速化
Dart VMはmakeの際に、 2回 buildを行う。
1回目は dart_no_snapshotを buildし、 SDKの coreを読み込み起動。
coreの dart srcを scanし、 snapshot、 snapshot_buffer[]に書き出し。
2回目で snapshot_buffer[]を取り込んで dartを buildする。 +400kbyte
dartは Coreの I/Oと Scanを skipできるので、起動時間が短縮できる。
--time-bootstrapオプションで比較可能。
bootstrapが短縮、 100,000micros -> 100micros
Coreの dart srcを readして scan vs. binaryから直接 deserialize
bootstrapの短縮
dart
dart_no_snapshot
0 100 200 300 400 500 600
410
410
430
540
fibo(40)の実行時間 (ms)
fibo
time
130ms
20ms起動時のオーバーヘッドが 1/6scanが 100msから 0.1msに
Isolate間のMessagePassing
Isolate
port_map
Isolate
ThreadThread
相手の Isolateにmessageを送るReceivePortを
全部mappingしてある
SnapshotReaderdeserialize
SnapshotWriterserialize
MessageHandler
MessageHandlerTask
MessageHandlerTask
MessageHandler
Main script
Thread
Isolateの StartUp(1)
Isolate
port_map
MessageHandler
MessageHandlerTask
TaskがThreadを生成
1個だけIsolateの初期化
mainが終わったら、MessageHandlerで
EventLoop
並行してMessageReceive
Async micro task残っている限り仕事し続ける。
threadpool
dart.ccのmain()関数
Thread
Isolateの StartUp(2)
Isolate
port_map
MessageHandler
MessageHandlerTask
mainが終わったら、MessageHandlerで
EventLoop
Unhandled exception:type 'double' is not a subtype of type 'int' of 'num'.#0 func (file:///syntax/lib/diff/future.dart:28:13)#1 main (file:///syntax/lib/diff/future.dart:33:7)#2 _startIsolate.isolateStartHandler (dart:isolate-patch/isolate_patch.dart:216)#3 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:115)
MessageReceive
async taskが残っている限り仕事し続ける。
Main script
MessageHandler and EventLoop
1.mainの起動
2.streamFibo
3.scheduleMicroTask
4.main終了
6.async task
https://www.dartlang.org/articles/eventloop/
Async系のmicrotaskはmainscriptが
終了後に実行する。
5.run microTask
MessageHandler and EventLoop
仮にここの asyncで errorになったら
2.streamFibo
3.Loop
#4 Stream.forEach.<anonymous closure> (dart:async/stream.dart:473)#5 _rootRunUnary (dart:async/zone.dart:695)#6 _RootZone.runUnary (dart:async/zone.dart:834)#7 _BaseZone.runUnaryGuarded (dart:async/zone.dart:546)#8 _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:333)#9 _DelayedData.perform (dart:async/stream_impl.dart:585)#10 _StreamImplEvents.handleNext (dart:async/stream_impl.dart:701)#11 _PendingEvents.schedule.<anonymous closure> (dart:async/stream_impl.dart:661)#12 _asyncRunCallback (dart:async/schedule_microtask.dart:18)#13 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:119)
EventLoop And Zone
zone
zone
root_zone
Zoneは RootZoneから parentが forkして
木構造でつながる。
scheduleMicrotaskで 1Thradで順次実行
Zoneの木構造を辿り実行
Dart VMの特長ここから VMの雑学
JITコンパイル
Dart VM Architectureと Isolate
Snapshotと高速起動
Message passingと Event Driven
Optional Typing & Generics & Checked Mode
Dartium
Dart Optional Typing
Dartには production modeと checked modeがある。
Dartには 3つのフェーズがある。
analyzerフェーズ。 IDEによる error/warningの検出
compileフェーズ。 script実行前の jit compile時に error/warning検出
runtimeフェーズ。実行時の型情報を validationする。
checked modeでは、 compileフェーズで型エラー /warningを無視しない。
compile時に型情報の validation命令を挿入し、実行時に assertする。
Dartの型は、 type annotationによる validationと割り切っている。
validationのタイミングは上記 3つ。 runtimeに影響を与えない。
Dart Optional Typing
Dartの型の違反は、基本的にwarning扱い
何が errorで何が warningかは、他の言語と比較すると結構曖昧かも。
int sum = 100 + 100.0;
int num = 100.0;
Breaking on exception:type 'double' is not a subtype of type 'int' of 'num'.
Breaking on exception:type 'double' is not a subtype of type 'int' of 'num'.
IDE/コンパイル時にwarningと分かるし、binaryoperator(+)の 2引数の validation命令を
JITコンパイル時に挿入する。実行時に validationされて warning
こちらは =の assignに validation版の命令をJITコンパイル時に挿入する。実行時に validationされて warning
Dart Generics
Classの Reified Genericsのみ (型パラメータを保存する領域あり )
Genericsを使用した場合のみ、 Classのインスタンスを newする際に、
型パラメータを保存する命令を挿入する。
TypeArgumentsっていう IRが存在する。
型パラメータは、実行時にいつでも参照できる。
Method genericsは存在しない。
型パラメータを参照するのは、 checked modeのみ。
Genericsの型パラメータも validationされる。
dartium
Dartium
dart runtime
sdk/libsdk/lib/html
Auto-generated library
Web IDL
runtime/include
native symbol
dartiumで定義されたシンボルを Native Extensionsを使用して直接呼出て連携する。
dartiumからの制御はincludeで定義された
API経由でdart runtimeに指示
標準化された APIをIDLから自動生成
dartium連携用
Dartiumの binding
Bindings (Dart API)
Dart VM
dartium/src/third_party/WebKit/Source/bindings/dartdartium/src/third_party/WebKit/Source/bindings/v8
Dartのページを読み込んだ場合のみ起動VMの遅延ローディング
JavaScriptV8
今後の予想
ChromeにDart VMを搭載するのでは。早ければ 2015年?
WebKitから Blinkになりましたし、邪魔する人はいないはず
まずはOilpan(GC for Blink)でメモリリークを解消してから?
http://goo.gl/gCugZ4
ARM + Android上でも動くため、
モバイルのChromeにも問題なく搭載できるのでは?
モバイル最速の VMかもだけど、
V8とDart VMの同時起動はメモリ食いそう。。