2014 dart flight school in Tokyo

Preview:

DESCRIPTION

2014 dart flight school in Tokyo dart vm overview

Citation preview

Dart VMの紹介

Outline Dart VM 1.1 Dart2js 1.1 Dart VMの特長

2014/02/22 Dart Flight School 2014 Tokyo

nothingcosmos <nothingcosmos@gmail.com>

自己紹介

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/event­loop/

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の同時起動はメモリ食いそう。。