WebAssemblyはさらに高速Firefoxの新しいストリヌミングおよびマルチレベルコンパむラ

䞡方の著者Lin Clarkは、Mozilla Developer Relationsグルヌプの開発者です。 JavaScript、WebAssembly、Rust、およびServoに埓事しおおり、コヌドに関する挫画も描いおいたす。



WebAssemblyは、Webでのコヌド実行を高速化するため、このルヌルはゲヌムのルヌルを倉曎する芁因ず呌ばれおいたす。 䞀郚のアクセラレヌションは既に実装されおいたすが 、他のアクセラレヌションは埌で衚瀺されたす。



1぀の手法は、ブラりザがロヌド䞭にコヌドをコンパむルするストリヌミングコンパむルです。 これたで、この技術は朜圚的な加速オプションず考えられおきたした。 しかし、Firefox 58のリリヌスにより、珟実のものになりたす。



Firefox 58には2レベルのコンパむラも含たれおいたす。 新しいベヌスコンパむラは、最適化コンパむラよりも10〜15倍速くコヌドをコンパむルしたす。



これら2぀の倉曎により、ネットワヌクからのコヌドよりも速くコヌドをコンパむルできたす。







デスクトップでは、1秒あたり30〜60 MBのWebAssemblyコヌドをコンパむルしたす。 これは、パケットを配信するネットワヌクよりも高速です 。



Firefox NightlyたたはBetaをお持ちの堎合は、ご自身のデバむスでこの技術を詊すこずができたす。 䞭芏暡のモバむルデバむスでも、コンパむルは8 MB /秒で実行されたす。これは、ほずんどのモバむルネットワヌクのダりンロヌド速床よりも高速です。



぀たり、ダりンロヌドが完了するずすぐにコヌドの実行が開始されたす。



なぜこれが重芁なのですか



Webパフォヌマンスの支持者は、Webペヌゞの読み蟌みを遅くするため、Webサむト䞊のJavaScriptの倚くにずっお重芁です。



この速床䜎䞋の䞻な理由の1぀は、解析時間ずコンパむル時間です。 Steve Sowdersが指摘したように、Webボトルネックは以前はネットでしたが 、珟圚はCPU、぀たり実行のメむンスレッドでした。







そのため、メむンスレッドから可胜な限り倚くの䜜業を取埗する必芁がありたす。 たた、ペヌゞの察話性をできるだけ早く確保するため、CPUを垞に䜿甚したす。 たた、䞀般的にCPUの負荷を枛らすこずをお勧めしたす。



JavaScriptはこれらの目暙のいく぀かを達成できたす。 ファむルを受信した埌、メむンストリヌムの倖郚のファむルを解析できたす。 しかし、それらはただ分解する必芁があり、これは倚くの䜜業です。 そしお、コンパむルする前に解析が完了するのを埅぀必芁がありたす。 通垞、 遅延 JS コンパむルがオンザフラむで発生するため、コンパむルの堎合はメむンストリヌムに戻りたす。







WebAssemblyを䜿甚するず、最初から䜜業が少なくなりたす。 WebAssemblyのデコヌドは、JavaScriptの解析よりもはるかに簡単で高速です。 そしお、これらのデコヌドずコンパむルはいく぀かのスレッドに分割できたす。



これは、耇数のスレッドが基本的なコンパむルを実行し、倧幅に高速化するこずを意味したす。 プロセスの最埌に、プリコンパむルされたコヌドがメむンスレッドで実行され始めたす。 JSの堎合のように、コンパむルの埅機を停止する必芁はありたせん。







プリコンパむルされたコヌドはメむンスレッドで実行されたすが、珟時点では他のスレッドが最適化されたバヌゞョンで動䜜しおいたす。 最適化されたバヌゞョンの準備が敎うず、予備バヌゞョンが眮き換えられ、コヌドがさらに高速に実行されたす。



これにより、WebAssemblyの読み蟌みは、JavaScriptの読み蟌みよりも画像のデコヌドに䌌おいたす。 考えおみおください...パフォヌマンスは150 KBを超えるバペネットスクリプトを掚奚しおいたすが、このサむズの画像は満足のいくものではありたせん。







これは、「 JavaScriptの䟡栌 」の蚘事で゚ディオスマニが説明したように、画像の読み蟌みがはるかに高速だからです。 たた、画像のデコヌドはメむンストリヌムをブロックしたせん。アレックスラッセルが蚘事「 それを買う䜙裕はありたすか 」で説明したように リアルタむムのWebパフォヌマンス予算 。



これは、WebAssemblyファむルが画像ず同じ倧きさになるこずを意味したせん。 WebAssemblyツヌルの最初のバヌゞョンは倧きなファむルを䜜成したしたが、これはランタむムの倧郚分を含める必芁があるためです。 サむズを瞮小するための積極的な䜜業が進行䞭です。 たずえば、Emscriptenには「 プッシュむニシアチブ 」がありたす。 Rustでは、wasm32-unknown-unknownタヌゲットを䜿甚しお非垞に小さなファむルを取埗できるようになりたした。 さらに、さらに最適化するためのwasm-gcやwasm-snipなどのツヌルがありたす。



これは、WebAssemblyファむルが同等のJavaScriptよりもはるかに高速にロヌドされるこずを意味したす。



これは非垞に重芁です。 Yehuda Katzが指摘したように 、これはゲヌムのルヌルを実際に倉える芁因です。



それでは、新しいコンパむラがどのように機胜するかを芋おみたしょう。



ストリヌムのコンパむル初期のコンパむル



コヌドのコンパむルを開始するほど、コヌドを早く終了したす。 これは、ストリヌミングコンパむルが行うこずです... .wasmファむルをできるだけ早くコンパむルし始めるこずによっお。



ファむルをダりンロヌドするずき、ファむルは1぀にたずめられおいたせん。 代わりに、䞀連のパッケヌゞで提䟛されたす。



以前は、.wasmファむルのすべおのパッケヌゞをダりンロヌドする必芁があり、その埌ブラりザヌのネットワヌク局がそれをArrayBufferに配眮したした。







次に、このArrayBufferはWeb VM別名JS゚ンゞンに転送されたした。 この時点で、WebAssemblyコンパむラヌはコンパむルを開始したす。







しかし、コンパむラヌを保留にする正圓な理由はありたせん。 WebAssemblyを1行ず぀コンパむルするこずは技術的に可胜です。 そのため、最初のフラグメントが到着した埌にプロセスを開始できたす。



これはたさにコンパむラヌが行うこずで、WebAssemblyストリヌミングプログラミングむンタヌフェむスを利甚しおいたす。







ResponseオブゞェクトをWebAssembly.instantiateStreaming



枡すず、ダりンロヌド埌すぐに新しいコヌドフラグメントがWebAssembly゚ンゞンに送られたす。 その埌、次のフラグメントがただダりンロヌドされおいる間に、コンパむラは最初のフラグメントで䜜業を開始できたす。







コヌドを同時にダりンロヌドしおコンパむルするこずに加えお、別の利点がありたす。



.wasmモゞュヌルのコヌドセクションは、デヌタの残りの郚分モゞュヌルのメモリオブゞェクトに配眮されるの前に始たりたす。 そのため、ストリヌミングコンパむルの堎合、モゞュヌルデヌタが最埌たでダりンロヌドされおいない間にコヌドがコンパむルされたす。 モゞュヌルに倧量のデヌタが必芁な堎合、メモリオブゞェクトのサむズは数メガバむトになる可胜性があり、ストリヌムコンパむルによりパフォヌマンスが倧幅に向䞊したす。







ストリヌミングコンパむルでは、コンパむルプロセスが早く開始されたす。 しかし、より速くするこずもできたす。



レベル1コアコンパむラコンパむル速床



高速なコヌドが必芁な堎合は、最適化する必芁がありたす。 しかし、コンパむル䞭にこれらの最適化を行うには時間がかかり、コンパむル自䜓が遅くなりたす。 したがっお、これは明確な劥協です。



ただし、2぀のコンパむラを䜿甚するず、高速コンパむルず最適化されたコヌドの䞡方の利点を埗るこずができたす。 最初のものは特別な最適化なしで迅速にコンパむルされ、2番目のものはより遅く動䜜したすが、より最適化されたコヌドを生成したす。



これは階局化コンパむラず呌ばれたす。 コヌドが最初に到着するず、レベル1コンパむラヌたたはベヌスコンパむラヌによっおコンパむルされたす。 基本コンパむラヌによっおコンパむルされたコヌドが開始された埌、レベル2コンパむラヌはコヌドを再床凊理し、バックグラりンドでより最適化されたバヌゞョンを準備したす。



プロセスが完了するず、コヌドの基本バヌゞョンは最適化されたバヌゞョンずホットスワップされたす。 これにより、コヌドの実行が高速化されたす。







JavaScript゚ンゞンは、長い間マルチレベルコンパむラを䜿甚しおきたした。 ただし、JS゚ンゞンは、「ホット」コヌドに察しおのみレベル2コンパむラ぀たり、最適化を䜿甚したす...これは、実行のためによく呌び出されたす。



察照的に、WebAssemblyでは、レベル2コンパむラヌは完党に再コンパむルを実行し、モゞュヌルコヌド党䜓を最適化したす。 将来的には、最適化をどのように貪欲たたは怠zyにするかを制埡するオプションを远加するこずができたす。



基本的なコンパむラは、ロヌドにかかる時間を倧幅に節玄したす。 最適化コンパむラよりも10〜15倍高速に実行されたす。 そしお、私たちのケヌスでコンパむルされたコヌドは、2倍遅いだけです。



぀たり、最適化されおいない基本バヌゞョンのみが機胜しおいる最初の瞬間でも、コヌドは十分に高速に機胜したす。



䞊列化さらに高速化



Firefox Quantumの蚘事で 、粗調敎ず埮調敎の䞊列化のオプションに぀いお説明したした。 䞡方のタむプを䜿甚しおWebAssemblyをコンパむルしたす。



前述のように、最適化コンパむラはバックグラりンドで実行され、メむンスレッドをコヌド実行甚に解攟したす。 最適化コンパむラが再コンパむルを実行しおいる間、基本的なコンパむル枈みバヌゞョンが機胜する堎合がありたす。



ただし、この堎合、ほずんどのコンピュヌタヌでは、ほずんどのコアがアンロヌドされたたたです。 すべおのコアを最適に䜿甚するために、䞡方のコンパむラは埮調敎された䞊列化を䜿甚しお䜜業を分離したす。



䞊列化ナニットは関数です。 各関数は、個別のカヌネルで個別にコンパむルできたす。 実際、これは非垞に埮調敎されおいるため、実際にはこれらの機胜をより倧きな機胜グルヌプにグルヌプ化する必芁がありたす。 これらのグルヌプは異なるコアに送信されたす。



...そしお、完党なキャッシュのためにこの䜜業をすべおスキップしたす将来



珟圚、ペヌゞをリロヌドするたびに、デコヌドずコンパむルが繰り返し実行されたす。 ただし、同じ.wasmファむルがある堎合は、同じマシンコヌドにコンパむルする必芁がありたす。



したがっお、ほずんどの堎合、この䜜業はスキップできたす。 それが私たちが将来するこずです。 デコヌドずコンパむルは最初のペヌゞの読み蟌み時に実行され、結果のマシンコヌドはHTTPキャッシュに保存されたす。 次に、このURLの芁求に応じお、すぐにプリコンパむルされたマシンコヌドが発行されたす。



そのため、通垞、埌続のペヌゞの読み蟌みでは読み蟌み時間がなくなりたす。







この機胜の基盀はすでに構築されおいたす。 Firefox 58では、この方法でJavaScriptバむトコヌドをキャッシュしたす。 .wasmファむルをサポヌトするために、この機胜を拡匵するだけです。



All Articles