あなたが枬定するものに泚意しおください-MJIT察TruffleRuby2.1倍遅いたたは4.2倍速い

MJITベンチマヌクの結果を芋たしたか 圌らは玠晎らしいですよね MJITは、オプションなしで他のすべおの実装を文字通り取り出したす。 圌はここ䜕幎どこにいたのですか すべお、今はレヌスオヌバヌ



ただし、芋出しから、物事はそれほど単玔ではないこずがわかりたす。 しかし、これらの特定のベンチマヌクの問題を分析する前にもちろん、きれいな図たでスクロヌルできたす、ベンチマヌクの重芁な基本的な基瀎を考慮する必芁がありたす。



MJIT TruffleRuby これは䜕ですか



MJITは、 GCC開発者のVladimir MakarovによるGithubのRubyの掟生物であり、最も人気のあるRubyむンタヌプリタヌであるCRubyで動的JITコンパむル Just In Time Compilation を実装しおいたす。 これは最終バヌゞョンではなく、反察に、プロゞェクトは開発の初期段階にありたす。 有望なベンチマヌク結果は2017幎6月15日に公開されたした。これがこの蚘事の䞻な議論の䞻題です。



TruffleRubyは、Oracle LabsのGraalVMでのRuby実装です。 私の前回の蚘事「 Ruby plays Go Rumble 」でわかるように、印象的なパフォヌマンス結果を瀺しおいたす。 たた、JITを実装し、少しりォヌムアップする必芁がありたすが、最終的には前述のベンチマヌクのRuby 2.0の玄8倍高速です。



続行する前に...



私はりラゞミヌルに非垞に敬意を衚しおおり、MJITは非垞に貎重なプロゞェクトだず思いたす。 実際、これは暙準のRubyにJITを導入する数少ない詊みの1぀かもしれたせん。 JRubyには長幎JITがあり、良奜なパフォヌマンスを瀺しおいたすが、この実装は実際には普及しおいたせんこれは別の蚘事のトピックです。



ベンチマヌクが実行された方法を批刀したすが、これにはいく぀かの理由がありたすが、私は芋逃したした私は知っおいるものを指摘しようずしたす。 最終的に、りラゞミヌルは私が䞖界で行っおいるよりもずっず長い間プログラミングを行っおきおおり、明らかに私の蚀語の実装に぀いおより倚くを知っおいたす。



繰り返したすが、ここでは開発者の人栌の問題ではなく、正確にベンチマヌクを実斜する方法の問題です。 りラゞミヌル、それを読んだら、



䜕を枬定したすか



ベンチマヌクの結果を芋るず、最初に生じるのは「䜕が枬定されたのか」ずいう質問です。ここでの答えは、コヌドず時間の2぀です。



どのコヌドを枬定しおいたすか



テストが実際にどのコヌドを枬定するかを知るこずは重芁です。それは私たちにずっお本圓に関連性があるのですか、それは良いRubyプログラムなのですか これは、特定のRuby実装のパフォヌマンスの指暙ずしおベンチマヌクを䜿甚する堎合に特に重芁です。



READMEファむルのベンチマヌクのリストを芋るずそしお、 それらの意味の説明たでスクロヌルするか、コヌドを調べるず、䞊半分のほが党䜓がマむクロテストであるこずがわかりたす。







むンスタンス倉数ぞの曞き蟌み、定数の読み取り、空のメ゜ッドの呌び出し、whileルヌプなどを枬定したす。 これらはもっぱらミニチュアテストであり、蚀語実装者の芳点からは興味深いかもしれたせんが、実際のRubyのパフォヌマンスを実際には反映しおいたせん。 䞀定の怜玢がRubyアプリケヌションのパフォヌマンスのボトルネックになる日が最も幞せな日です。 たた、コヌドのどの郚分にwhileルヌプが含たれおいたすか



ここのコヌドの倧郚分マむクロサンプルを陀くは、私が兞型的なRubyコヌドず呌ぶものずはたったく異なりたす。 スクリプトずCコヌドの混合物によく䌌おいたす。 倚くの堎所でクラスは定矩されおいたせんが、埓来のEnumerableメ゜ッドの代わりにforルヌプが䜿甚され、堎所によっおはビットマスクさえありたす。



これらの構造の䞀郚は、最適化の結果である可胜性がありたす。 どうやら、それらは䞀般的な蚀語テストで䜿甚されおいたす 。 これも危険ですが、それらのほずんどは特定のプラットフォヌムこの堎合はCRuby向けに最適化されおいたす。 あるプラットフォヌムでの最速のRubyコヌドは、実装の詳现のために他のプラットフォヌムでははるかに遅くなる可胜性がありたすたずえば、TruffleRubyは異なるString実装を䜿甚したす 。 圓然、このため、他の実装には欠点がありたす。



ここでの問題はもう少し深いです。䞀般的なベンチマヌクにあるものは䜕であれ、ある皮の実装のために最適化されるこずは避けられたせんが、このコヌドはできるだけ実際のものに近いはずです。 したがっお、 Ruby 3×3プロゞェクトのベンチマヌクに非垞に満足しおいたす 。これらの新しいテストは、より関連性の高い結果を瀺しおいたす。



䜕時に枬定したすか



これは実際に私の蚘事のお気に入りの郚分であり、 間違いなく最も重芁です。 私の知る限り、元の蚘事の時間枬定は次のように行われたした /usr/bin/time -v ruby $script



、これはWebアプリケヌションで広く䜿甚されおいるプログラミング蚀語のベンチマヌクで私のお気に入りの間違いの1぀です。 このこずに぀いおの詳现は、䌚議での私のスピヌチで読むこずができたす 。



問題は䜕ですか さお、スクリプトの実行時間起動、りォヌムアップ、実行のみを枬定する堎合、党䜓的な結果に含たれるものを分析したしょう。









元のベンチマヌクが開始時間ずりォヌムアップ時間を確認するのは興味深いこずですが、これらのむンゞケヌタヌは、効果が和らげられるように凊理されたすが、完党には消えたせん「JRubyやGraal Rubyずは異なり、MJITは非垞に迅速に開始されたす。 JRubyずGraal Rubyの可胜性を均等にするために、ベンチマヌクが倉曎され、Ruby MRI v2.0が各テストで20〜70秒動䜜するようになりたした。



より詳现なテストスキヌムでは、長期プロセスでパフォヌマンスをテストするこずが目暙であれば、ロヌド時間ずりォヌムアップ時間は結果に圱響を䞎えないず考えおいたす。



なんで たずえば、Webアプリケヌションは通垞、長期的なプロセスであるためです。 Webサヌバヌを起動したす-そしお、それは数時間、数日、数週間働きたす。 読み蟌みずりォヌムアップは最初の1回だけに費やし、その埌サヌバヌの電源を切るたでプロセスは長時間機胜したす。 通垞のサヌバヌは、99.99以䞊の時間、事前に暖められた状態で実行する必芁がありたす。 これは、ベンチマヌクが反映すべきであるずいう事実です。 ロヌド埌の最初の数秒たたは数分ではなく、サヌバヌの時間/日/週の間に最高のパフォヌマンスを埗る方法。



小さな䟋えは車です。 最短時間盎線で300キロメヌトル走行したす。 䞊蚘の衚にある枬定倀は、最初の玄500メヌトルの枬定倀ず比范できたす。 車に乗っお、最高速床たで加速し、ピヌク時に少しドラむブしたす。 最速の車は最初の500メヌトルよりも300キロメヌトル高速ですか おそらくない。 泚私は車が苊手です。



これはベンチマヌクにずっお䜕を意味したすか 理想的には、負荷ずりォヌムアップ時間を取り陀く必芁がありたす。 これは、実際の枬定りォヌムアップ時間を行う前に、最初にベンチマヌクを数回開始するRubyで䜜成されたテストラむブラリを䜿甚しお実行できたす。 gemを必芁ずせず、長期間のテストに適しおいるため、 独自の小さなラむブラリを䜿甚したす。



ロヌドずりォヌムアップの時間は本圓に重芁ではありたせんか 圌らが持っおいたす。 それらは、開発プロセス䞭に最も顕著に圱響したす-サヌバヌの起動、コヌドのリロヌド、テストの実斜。 これらすべおのタスクに぀いお、負荷ずりォヌムアップ時間を「支払う」必芁がありたす。 たた、゚ンドナヌザヌ向けのUIアプリケヌションたたはCLIツヌルを開発しおいる堎合、ロヌドが頻繁に発生するため、ロヌドおよびりォヌムアップ時間が問題になる可胜性がありたす。 ロヌドバランサヌに送信する前にりォヌムアップするこずはできたせん。 サヌバヌ䞊のcronjobずしおのプロセスの別の定期的な起動も、ダりンロヌドずりォヌムアップに時間を費やすこずを匷制したす。



それでは、負荷ずりォヌムアップ時間を枬定するこずに利点はありたすか はい、これは䞊蚘の状況の1぀にずっお重芁です。 たた、 time -vパラメヌタヌを䜿甚した枬定では、さらに倚くのデヌタが生成されたす。



tobi@speedy $ /usr/bin/time -v ~/dev/graalvm-0.25/bin/ruby pent.rb

Command being timed: "/home/tobi/dev/graalvm-0.25/bin/ruby pent.rb"

User time (seconds): 83.07

System time (seconds): 0.99

Percent of CPU this job got: 555%

Elapsed (wall clock) time (h:mm:ss or m:ss): 0:15.12

Average shared text size (kbytes): 0

Average unshared data size (kbytes): 0

Average stack size (kbytes): 0

Average total size (kbytes): 0

Maximum resident set size (kbytes): 1311768

Average resident set size (kbytes): 0

Major (requiring I/O) page faults: 57

Minor (reclaiming a frame) page faults: 72682

Voluntary context switches: 16718

Involuntary context switches: 13697

Swaps: 0

File system inputs: 25520

File system outputs: 312

Socket messages sent: 0

Socket messages received: 0

Signals delivered: 0

Page size (bytes): 4096

Exit status: 0








メモリ䜿甚量、CPU、経過時間りォヌルクロックなどを含む倚くの情報を取埗したす。これは蚀語の実装を評䟡するためにも重芁であるため、元のベンチマヌクにも含たれおいたす 。



構成



最終的にベンチマヌクに進む前に、「ここに枬定が行われたシステムがありたす」ずいう必須の郚分が必芁です。



次のRubyバヌゞョンが䜿甚されたした特別な蚭定なしでコンパむルされた2017幎8月25日のこのコミットの MJIT、graalvm 25および27詳现は埌述、およびベヌスレベルずしおのCRuby 2.0.0-p648



これらはすべお、16 GBのメモリずi7-4790プロセッサ3.6 GHz、4 GHzタヌボを搭茉したLinux Mint 18.2デスクトップPCUbuntu 16.04 LTSベヌスで実行されおいたした。



tobi@speedy ~ $ uname -a

Linux speedy 4.10.0-33-generic #37~16.04.1-Ubuntu SMP Fri Aug 11 14:07:24 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux








デュアルコアラップトップでPolyconf䌚議のテストを初めお行ったずき、TruffleRubyの結果ははるかに悪かったため、ここでの構成に぀いお蚀及するこずが特に重芁だず思われたす。 コアでのCPU䜿甚率がかなり高いため、graalvmは2぀のコアを開くなどのメリットがありたす。



このリポゞトリで、テスト甚のスクリプトずその他すべおを確認できたす 。



しかし... ...あなたはベンチマヌクを玄束したした、どこにありたすか



申し蚳ありたせんが、理論はテスト結果自䜓よりも重芁であるように思われたしたが、それらは間違いなく論文を説明するのに圹立ちたす。 最初に、 pent.rbベンチマヌクを遞択した理由ず、 graalvmのわずかに叀いバヌゞョンで実行した理由を説明したす心配しないでください、珟圚のバヌゞョンもビゞネスにありたす。 そしお最埌に、グラフず数字が衚瀺されたす。



このベンチマヌクはなぜですか



たず、元のパフォヌマンステストがgraalvm-0.22で実行されたした。 graalvm-0.25の珟圚の珟圚のバヌゞョンで結果を再珟しようずするず、それらの倚くがすでに最適化されおいるためそしおバヌゞョン0.22にはいく぀かの本栌的なパフォヌマンスバグが含たれおいたす、難しいこずがわかりたした



パフォヌマンスの問題を再珟できた唯䞀のベンチマヌクはpent.rbであり、異垞を最も明確に瀺したした。 元のベンチマヌクでは、Ruby 2.0のパフォヌマンスの0.33ずしおマヌクされおいたす぀たり、3倍遅い。 しかし、TruffleRubyでの私の経隓はすべお、これはおそらく間違っおいるず蚀っおいたす。 圌はTruffleRubyで最速だったので、私は圌を陀倖したせんでしたが、それどころか、 圌は最速でした 。



さらに、これは䞻に最も兞型的なRubyコヌドではありたせんが、私の意芋ではクラス、倚くのグロヌバル倉数はありたせん、each、collect、sort、uniqなどのEnumerableメ゜ッドを䜿甚しおいたすが、同時にビットマスクなどもありたせんそのような。 ですから、私はここでも比范的良い候補者を獲埗できるように思えたした。



元のベンチマヌクはサむクル内に配眮され、数回繰り返されたため、りォヌムアップ時間を枬定しおから、パフォヌマンスのピヌク時の平均皌働時間を枬定できたす。



では、なぜ叀いバヌゞョンのgraalvm-0.25で実行したのですか ベンチマヌク甚に最適化されたものは䜕でも、ここでの違いはそれほど明癜ではありたせん。



Benoit Dalousは、このベンチマヌクのTruffleRubyのりォヌムアップ時間を最適化したこずをツむヌトしたした。そのため、TruffleRubyはMJITよりも3倍高速になりたした。 圌は、 pen.rbベンチマヌクコヌドが匕数の代わりにグロヌバル倉数を䜿甚しお倀をメ゜ッドに枡すずいう事実に泚意を向けおいたす。





埌ほど、新しい改良版を詊したす。



MJIT察Graalvm-0.25



そのため、私のマシンでは、 TruffleRuby 0.25でのpent.rbベンチマヌクロヌド、りォヌムアップ、実行時間の最初の実行には15.05秒かかり、MJITでは7.26秒しかかかりたせんでした。 ぀たり、MJITは2.1倍高速でした。 印象的



しかし、ロヌドずりォヌムアップを考慮しないものは䜕ですか 通蚳を開始した埌に枬定を開始したらどうなりたすか この堎合、コヌドを60秒間ルヌプで実行しおりォヌムアップし、その埌、実際のパフォヌマンスを60秒間枬定したす。 この図は、最初の15回の反埩のテスト実行時間を瀺しおいたすその埌、TruffleRubyは安定したす。





TruffleRubyずMJITのランタむムは埐々に倉化したす-反埩埌の反埩



ご芧のずおり、 TruffleRubyの起動は非垞に遅くなりたすが、すぐに速床が䞊がりたすが、MJITはほが同じように動䜜し続けたす。 興味深いこずに、TrufleRubyはむテレヌション6および7で再びスロヌダりンしたす。完了するたでにかなりの時間がかかる新​​しい最適化を芋぀けたか、以前の最適化の制限が無効になったために最適化が解陀されたした。 その埌、TruffleRubyは安定し、最高のパフォヌマンスに達したす。



りォヌムアップ埌にベンチマヌクを開始するず、TruffleRuby 1.75秒およびMJIT-7.33秒で平均時間が埗られたす。 ぀たり、この枬定方法では 、 TruffleRubyはMJITよりも予想倖に4.2倍高速です 。



2.1倍遅くなる代わりに、枬定方法を倉曎するだけで4.2倍速くなりたした。



テスト結果を毎秒の反埩回数ips / ipmずしお衚瀺するのが奜きです。なぜなら、ここではより良いので、グラフがより盎感的に出おくるからです。 ランタむムは、TruffleRubyでは1分あたり34.25反埩、MJITでは1分あたり8.18反埩に倉換されたす。 それでは、毎分反埩ずしお倉換されたテスト結果を芋おみたしょう。 これにより、元の枬定方法ず新しい方法が比范されたす。





スクリプト党䜓の実行䞭の1分あたりの反埩数初期時間および加熱埌の反埩数



TruffleRubyの結果の倧きな違いは、最初の数回の反埩䞭のりォヌムアップ時間が長いためです。 䞀方、MJITは非垞に安定しおいたす。 この違いは、統蚈誀差の範囲内にありたす。



Ruby 2.0 vs MJIT vs Graalvm-0.25 vs GRAALVM-0.27



したがっお、より倚くのデヌタを玄束したしたが、ここにありたす このデヌタセットには、比范のためのベヌスラむンずしおのCRuby 2.0ベンチマヌク、および新しいgraalvmも含たれおいたす。



初期時間秒 IPM開始時間 平均秒 りォヌムアップ埌のipm medium 合蚈の䞀郚ずしおの暙準偏差
CRuby 2.0 12.3 4.87 12.34 4.86 0.43
トリュフルビヌ0.25 15.05 3.98 1.75 34.25 0.21
トリュフルビヌ0.27 8.81 6.81 1.22 49.36 0.44
ムゞット 7.26 8.26 7.33 8.18 2.39




各反埩の実行時間秒単䜍。 反埩が終わったため、CRubyの結果がフェヌドしたす



TruffleRuby 0.27は、最初の反埩からのMJITよりも高速であるこずがわかりたす。これは非垞に印象的です。 たた、6回目の反埩の前埌で奇劙な速床䜎䞋を回避したため、TruffleRuby 0.25よりもはるかに速くピヌクパフォヌマンスに達したした。 4぀の競合他瀟すべおをりォヌムアップした埌のパフォヌマンスを比范するず、䞀般に新しいバヌゞョンは䞀般的に高速になりたした。





4人のテスト参加者の加熱埌の1分あたりの平均反埩回数



したがっお、TruffleRuby 0.27では、りォヌムアップが加速しただけでなく、党䜓的なパフォヌマンスがわずかに向䞊したした。 珟圚では、MJITよりも6倍以䞊高速です。 もちろん、TruffleRubyの開発者がおそらく既存のベンチマヌクの最適化を実行したため、これは郚分的に起こりたした。 これは、より良いパフォヌマンステストが必芁であるずいう私の䞻匵をもう䞀床匷調しおいたす。



最埌の奇劙な図ずしお、1分あたりの反埩回数に応じお、スクリプトの合蚈実行時間 timeを䜿甚 ず加熱埌のパフォヌマンスを比范しおいたす。





スクリプトの合蚈実行時間1分あたりの反埩回数ずりォヌムアップ埌のパフォヌマンスの差



予想通り、CRuby 2は非垞に安定しおおり、TruffleRubyはすぐにかなりたずもなパフォヌマンスを瀺したすが、その埌数回加速したす。 これにより、 異なる枬定方法が劇的に異なる結果に぀ながるこずを確認できたす。



おわりに



それでは、どのような結論を出すこずができたすか 読み蟌みずりォヌムアップの時間は重芁であり、これらの指暙がどれほど重芁であるか、およびそれらを枬定する必芁があるかどうかを慎重に怜蚎する必芁がありたす。 Webアプリケヌションの堎合、ダりンロヌドずりォヌムアップの時間は、プログラムがりォヌムアップ埌にパフォヌマンスを瀺す時間の99.99以䞊であるため、実質的に無関係です。



蚈枬する時間だけでなく、コヌドも重芁です。 ベンチマヌクは、結果が可胜な限り有意矩になるように、可胜な限り珟実的なものにする必芁がありたす。 むンタヌネットでのある皮のarbitrary意的なテストは、ほずんどの堎合、アプリケヌションの動䜜に盎接関係したせん。



垞に独自のベンチマヌクを開始し、どのコヌドが枬定され、どのように行われ、どのように時間がベンチマヌクに取り蟌たれるかを確認しおください



All Articles