JIT ロードマップ / Ruby 3 さみっと

JIT ロードマップ / Ruby 3 さみっと

08d5432a5bc31e6d9edec87b94cb1db1?s=128

Takashi Kokubun

April 16, 2020
Tweet

Transcript

  1. Ruby 3 ͞Έͬͱ / k0kubun JIT ϩʔυϚοϓ Caveat: The slides

    and the talk are in Japanese. I'll publish its English version with updates when Ruby 3 is released.
  2. ୭ • GitHub, Twitter: k0kubun • RubyͷJITͷ։ൃΛ3೥͘Β͍΍͍ͬͯΔ • 2017/4 ~

    7: LLVMͰRubyͷJIT (LLRB) Λ։ൃ • 2017/9 ~ 10: RTL / MJIT [Feature #12589] ͷJITϑϨʔϜϫʔΫͱLLRBͷ YARV JITίϯύΠϥΛϚʔδͨ͠YARV-MJITΛ։ൃ [Feature #14235] • 2018/2: YARV-MJITΛCRubyຊମͷJITͱͯ͠Ϛʔδ • 2018 ~ 2020: CRubyͷJITͷੑೳվળ
  3. ࠓ೔࿩͢͜ͱ • Ruby 3ʹ͓͚ΔJITͷΰʔϧ • ੑೳܭଌํ๏ͷ෼ྨ • ϕϯνϚʔΫ໨ඪ • ໨ඪୡ੒ͷͨΊͷઓུ

    • جຊํ਑ • ϩʔυϚοϓ • ਐḿใࠂ • ࠷ۙͷ׆ಈ • ϩʔυϚοϓͷঢ়گ
  4. ࠓ೔࿩͞ͳ͍͜ͱ • RubyͷJIT͕ͲͷΑ͏ͳΞʔΩςΫνϟͳͷ͔ • ϒϩά: https://k0kubun.hatenablog.com/entry/ruby26-jit • աڈͷൃදࢿྉ: https://speakerdeck.com/k0kubun

  5. Ruby 3ʹ͓͚Δ JITͷΰʔϧ

  6. Ruby 3ʹ͓͚ΔJITͷΰʔϧ • Ruby 3x3: Ruby 3 ͸ Ruby 2.0

    ͷ3ഒߴ଎Խ • ͲͷΑ͏ͳܭଌํ๏ͱϕϯνͰ໨ඪΛઃఆ͢Δ͔?
  7. ੑೳܭଌํ๏ͷ෼ྨ

  8. ੑೳܭଌํ๏ͷ෼ྨ • Level 1: ίϯύΠϧޙܭଌ / JITϫʔΧʔఀࢭ / Ұ෦ͷΈίϯύΠϧର৅ •

    ܭଌର৅: Ұ෦ͷϝιουͷJITʹΑΔੑೳมԽ • Level 2: ίϯύΠϧޙܭଌ / JITϫʔΧʔఀࢭ • ܭଌର৅: ~100 ϝιουͷJITʹΑΔੑೳมԽ • Level 3: ίϯύΠϧޙܭଌ / JITϫʔΧʔ༗ޮ • ܭଌର৅: ~100 ϝιουͷJITʹΑΔੑೳมԽ, ίϯύΠϧର৅͕҆ఆ͠ͳ͍৔߹ͷෛՙ • Level 4: ίϯύΠϧதܭଌ / JITϫʔΧʔ༗ޮ • ܭଌର৅: ϕϯνϚʔΫதʹJITͰౕ͖ͨͷੑೳมԽ, CίϯύΠϥ͕૸Δෛՙ, JITίϯύΠϧதͷGCϩοΫ • Level 5: ίϯύΠϧதܭଌ / JITϫʔΧʔ༗ޮ (ϚϧνεϨου / Ϛϧνϓϩηε) • ܭଌର৅: ϕϯνϚʔΫதʹJITͰౕ͖ͨͷੑೳมԽ, CίϯύΠϥ͕૸Δෛՙ, JITίϯύΠϧதͷGCϩοΫ, εϨου΍ϓϩηε
  9. ੑೳܭଌํ๏ͷ෼ྨ • Level 1: ίϯύΠϧޙܭଌ / JITϫʔΧʔఀࢭ / Ұ෦ͷΈίϯύΠϧର৅ •

    ͜Ε͸׬શʹΠϯνΩͰɺௐࠪઐ༻ɻͰ΋Ұ൪؆୯ͳ͜Ε͕଎͘Ͱ͖ͳ͍ͳΒઈର଎͘ͳΒͳ͍ • Level 2: ίϯύΠϧޙܭଌ / JITϫʔΧʔఀࢭ • ੜ੒ίʔυͷ७ਮͳੑೳ͕ݟΕΔɻJITϫʔΧʔʹΑΔϊΠζΛഉআͯ͠VMͱJITੜ੒ίʔυͷੑೳࠩΛ७ਮʹൺֱ͢ΔͨΊʹ࢖͏ • Level 3: ίϯύΠϧޙܭଌ / JITϫʔΧʔ༗ޮ • ௕ظ࣮ߦ࣌ͷݱ࣮తͳੑೳௐࠪʹ࢖͏ɻHotͳάϧʔϓ͕҆ఆ͢Δ৔߹ɺཧ࿦্͸Level 2ͱಉ݁͡ՌʹͳΔ • Level 4: ίϯύΠϧதܭଌ / JITϫʔΧʔ༗ޮ • ىಈ࣌ͷ஗͞΋ؚΊͨݱ࣮తͳੑೳௐࠪʹ࢖͏ɻ • Level 5: ίϯύΠϧதܭଌ / JITϫʔΧʔ༗ޮ (ϚϧνεϨου / Ϛϧνϓϩηε) • αʔόʔ༻్Ͱͷݱ࣮తͳੑೳௐࠪʹ࢖ΘΕ͍ͯΔɻ΋ͪΖΜ࠷ޙ͸͜Ε͕ܭଌ͞ΕΔ΂͖͕ͩɺJITͷੑೳݕূʹ͸શવؔ܎ͳ ͍ϊΠζ͕ଟΊɻ
  10. ϕϯνϚʔΫ໨ඪ

  11. RubyॲཧܥͷϚΫϩͳϕϯνϚʔΫ • mame/optcarrot - RubyͷϕϯνϚʔΫ༻ʹ࡞ΒΕͨNESΤϛϡϨʔλ • benchmark-driver/sinatra - SinatraͰݻఆͷจࣈྻϨεϙϯεΛฦ͢ •

    k0kubun/railsbench - Railsͷ #show ΞΫγϣϯͷscaffold࣮૷ • noahgibbs/rsb - DiscourseΑΓγϯϓϧͱ͞Ε͍ͯΔRailsͷϕϯν • discourse/discourse - ϕϯνΛ࣋ͭ ϦΞϧϫʔϧυRailsΞϓϦέʔγϣϯ
  12. RubyॲཧܥͷϚΫϩͳϕϯνϚʔΫ • ଟ͘ͷϕϯνͰݱࡏվળର৅ʹ͍ͯ͠Δείʔϓ: Level 1~2 • Rails΍SinatraͷϕϯνͰ͸Level 1Ͱ΋ݱঢ়͋·Γ͕ࠩग़͍ͤͯͳ͍ • ੜ੒ίʔυͷੑೳͱແؔ܎ʹɺJITίϯύΠϧࡁΈϝιου͕૿͑Δ΄ͲͲ͏ͯ͠΋஗

    ͘ͳΔ໰୊(ޙड़)͕͋ΓɺLevel 2Ҏ্͸શͯͦΕͷ͍ͤͰ஗͍ (Α͏ʹݟ͑Δ) • OptcarrotϕϯνͰͷܭଌํ๏: Level 4 • ϑΣΞʹଞ࣮૷ͱൺֱΛߦͳ͏ʹ͸ݩͷϨΪϡϨʔγϣϯʹԊ͏Ҏ֎ͳ͍ͷͰ͜͏ͳΔ • Level 4Ͱ΋े෼վળͰ͖͍ͯΔ͕ɺܧଓతͳੑೳվળͷνΣοΫʹ͸ຊ౰͸Level 2~3 ΛݟΔ΂͖
  13. ϕϯνϚʔΫ໨ඪ Railsbench (Level 2 or 3) 5~10%+ Optcarrot 3.0x RSB

    or Discourse 5~10%+ Sinatra (Level 2 or 3) 5~10%+ Optcarrot 2.5x
  14. ϕϯνϚʔΫ໨ඪ Railsbench (Level 2 or 3) 5~10%+ Optcarrot 3.0x RSB

    or Discourse 5~10%+ Sinatra (Level 2 or 3) 5~10%+ Optcarrot 2.5x ✅
  15. ໨ඪୡ੒ͷͨΊͷઓུ

  16. ࠷దԽͷجຊํ਑ 1. ϘτϧωοΫʹͳ͍ͬͯΔ໰୊ͱͦͷཧ༝Λಛఆ 2. ͦͷ໰୊Λղܾ͢Δ͔ɺ೉͚͠Ε͹࣍ʹ஗͍ՕॴʹҠΔ

  17. ݱঢ়ϘτϧωοΫʹͳ͍ͬͯΔ໰୊ • ໰୊1. ݺͼग़͞ΕΔJITࡁΈϝιου͕૿͑Δ΄ͲɺJITੜ੒ίʔυΛݺͼग़͢ ·ͰͷϝϞϦΞΫηε͕஗͘ͳΔ • ໰୊2. ΠϯϥΠϯԽՄೳͳൣғ͕ݶΒΕ͍ͯΔ͍ͤͰ༷ʑͳ࠷దԽ͕ϒϩο Ϋ͞Ε͍ͯΔ

  18. ໰୊1: JITੜ੒ίʔυݺͼग़͠ͷεέʔϥϏϦςΟ • nilΛฦ͚ͩ͢ͷϝιουΛ100ݸ࡞ͬͯॱ൪ʹݺͼग़͍ͯ͘͠ͱɺ1ݸΛಉ͡ճ਺ݺͿͷʹൺ΂ͯJITࡁΈͷ৔߹ͱͯ΋஗͘ͳΔ • nilΛฦ࣮͢૷ͱ͔஗͘͠Α͏͕ͳ͍ • ΞηϯϒϥΛோΊɺRuby 3 Ͱ͸༨ܭͳ໋ྩΛશͯ࡟ͬͨ

    (ޙड़) ͕ɺผʹ͜Ε͸௚Βͳ͍ • ϩʔυํ๏ʹΑΔΠϯύΫτ͸͕͋ͬͨɺ͜Ε͸ՄೳͳݶΓվળͨ͠ • શ෦ίϯύΠϧ͠ऴΘͬͨΒશϝιουΛҰͭͷsoϑΝΠϧʹ·ͱΊͯશϦϩʔυ͍ͯ͠Δ • shinh͞Μ͕ॻ͍ͨobjϑΝΠϧϩʔμͱ΄΅ಉ͡ੑೳ͕ग़͍ͯΔͷͰɺଟ෼໰୊͸͜͜Ͱ͸ͳ͍ • Ͱ͸Կ͕஗͍ͷ͔? • ͓ͦΒ͘: όΠτίʔυΛ๊͑Δߏ଄ମΛಡΉͷ͕ແବʹ2Օॴ͋Δ + ੜ੒ίʔυͦͷ΋ͷͷϩʔυ͕Ωϟογϡ͔ΒᷓΕΔ • ͨͩ͠໌֬ͳࠜڌ͕ݟ͚ͭΒΕ͓ͯΒͣɺͲ͜ΛͲ͏௚͢΂͖͔ͷ֬ূ͕ಘΒΕ͍ͯͳ͍ (ຊ౰ʹ͜Ε͕ϘτϧωοΫͳͷ ͔͢Β໌֬Ͱ͸ͳ͍)
  19. ໰୊1ͷΞϓϩʔν • ·ͣ͜Ε͕Ͳͷఔ౓໰୊ʹͳ͍ͬͯΔ͔Λ໌֬ʹ೺Ѳ͢Δ: • શମͰͷӨڹ֬ೝʹ͸ޙड़ͷperf-profileΛࢼ͢ • खݩͷϚγϯͰϝϞϦ΍CPUͷΩϟογϡͷΞΫηεʹԿns͔͔Δ͔֬ೝ͠ɺͦΕ͕ͲͷՕॴͰԿճى͖͍ͯΔ͔Λperfͷevent ͰݟͯΈΔ • όΠτίʔυΛ๊͑Δߏ଄ମΛಡΉͷ͕ແବʹ2Օॴ͋Δ:

    • ଟ෼Ͳ͏ʹ͔Ͱ͖Δ (͕ɺຊ౰ʹ͜Ε͕ϘτϧωοΫʹͳΔ͔?) • Ruby 2.7ͷ࣌ʹॻ͍ͨύον΋͋Δ͕ɺͦΕ͸VMͷํʹΠϯύΫτ͕͋Δͷ͕ཁमਖ਼ • ੜ੒ίʔυͦͷ΋ͷͷϩʔυ͕Ωϟογϡ͔ΒᷓΕΔ: • ؔ਺ϙΠϯλΛܦ༝ͨ͠ݺͼग़͠ͷ਺Λ2͔ͭΒ1ͭʹ·ͱΊΔ͜ͱ͸Մೳ • Ruby 2.7ͷ࣌ͦΕΛ࣮ݧ͕ͨ͠ɺSinatra / RailsͷϕϯνʹޮՌ͕ͳ͘ɺղܾํ๏ͷਖ਼͠͞ʹ֬ূ͕ͳ͍ (ͳͷͰ໰୊ͷৄࡉௐࠪʹ ϒϩοΫ͞ΕΔ) • ؔઅݺͼग़͠Λ1͔Β0·ͰݮΒ͢ʹ͸ɺΠϯϥΠϯԽ͕࢖͑Δ͔΋
  20. ໰୊2: ΠϯϥΠϯԽՄೳͳൣғ͕ݶΒΕ͍ͯΔ • Rubyͷϝιουݺͼग़͠ͷΠϯϥΠϯԽ͸Ruby 2.7Ͱೖͬͨ • ͨͩ͠ΠϯϥΠϯԽ͢ΔͱOptcarrotͷfps͕མͪΔ܏޲ʹ͋Γ(ίϯύΠϧ࣌ؒ΁ͷӨڹ͔ɺίʔυαΠζ ͷ໰୊͔)ɺ΄ͱΜͲ࢖ΘΕͳ͍ঢ়ଶʹͯ͋͠Δ • ͦΕ͔ΒɺϑϨʔϜͷpush/pop΋࡟ΔΠϯϥΠϯԽ͕Ͱ͖Δ৚݅͸·͔ͩͳΓݶΓ͕͋Δ

    (ϩʔΧϧม਺ʹ ·ͩରԠͯ͠ͳ͍ɺͳͲ) • ࠶ؼ͢Δ৔߹ʹࣗ਎ͷωΠςΟϒؔ਺Λݺͼग़ౕ͢΋લೖΕ͍͕ͯͨɺόάͬͯrevert • Rubyͷϝιουͷsuper΍yield͸·ͨผͷέΞ͕ඞཁ • CͷϝιουͷΠϯϥΠϯԽ͸·ͩೖ͍ͬͯͳ͍ • ͜Εͷ४උʹඞཁͳ࢓૊ΈΛ͍ΕΔͱOptcarrotͷfps͕མͪΔ໰୊͕͋ͬͨ • attr_readerͷΠϯϥΠϯԽΛ͔ͳΓલʹೖΕ͍͕ͯͨɺόάͬͯrevert
  21. ໰୊2ͷΞϓϩʔν • ࣮૷͸ຊ࣭తʹ͸೉͘͠ͳ͍ • όάͰSEGVΛ1ͭੜΉ͝ͱʹҰ൩͔Β਺೔ফ໓͢Δͱ͍͏໰୊͸͋Δ • ΠϯϥΠϯԽ͢Δʹ͸͠͹͠͹࣮૷Λॏෳͤ͞Δඞཁ͕͋Δ͕: • ՄೳͳݶΓVMͱ࣮૷Λڞ༗Ͱ͖ΔΑ͏ؔ਺ʹڞ௨෦෼Λ੾Γग़͢ •

    ͦ΋ͦ΋ΠϯϥΠϯԽ͠ͳ͍ͱ͍͚ͳ͍είʔϓΛ࠷ॳ͔ΒॖΊͯ͠·͏ͨΊʹɺ"fastpath" ͱ͍͏ ػߏΛ࢖͏ • fastpath: ϝιουσΟεύον͸ؔ਺ϙΠϯλΛܦ༝ͯ͠ߦͳΘΕΔ͕ɺ࠷దԽՄೳͳ࣌ʹؔ਺ϙ Πϯλͱͯ͠ηοτ͞ΕΔΑΓγϯϓϧͳύε͕fastpath • JITͰͷΈ࣮૷είʔϓΛڱΊΔͱಉ͡ڍಈ͕ςετ͞ΕΔػձ͕গͳ͘όάΓ΍͘͢ͳΔ͠ɺ͍ͭ ͷ·ʹ͔VMͱ࣮૷͕ဃ཭͠΍͍͢
  22. ໰୊1ͱ໰୊2ͷ࣍͸…? • ໰୊1Λղ͍ͯ΋ɺ஗͘ͳΒͳ͘ͳΔ͚ͩͰɺ୯ಠͰ͸໨ඪୡ੒ʹͳΒͳ͍ • ໰୊2Λ΍Δͱɺ࢓૊Έ্CίϯύΠϥ͕͋Δఔ౓଎͘͸ͯ͘͠ΕΔ͕ɺΠϯ ϥΠϯԽͦͷ΋ͷ͸ຊ࣭తʹ͸࠷దԽͰ͸ͳ͍ • ΑΓ଎͍ͯ͘͘͠ʹ͸ɺͲΜͲΜ࠷దԽΛ଍͍ͯ͘͠ඞཁ͕͋Δ

  23. ޮՌ͕ߴ͍ͱࢥΘΕΔ࠷దԽ • ࣮ߦ࣌৘ใΛ࢖ͬͨΠϯϥΠϯԽͱɺ࣮૷ͷ୯७ԽΛ܁Γฦ͢ • Constant folding • Dead code elimination

    • Loop-invariant code motion • ϝϞϦΞΫηεͷ࠷దԽ • ώʔϓ > ελοΫ > Ϩδελ > ଈ஋
  24. RubyͷJITͷ࢓૊ΈͰͦΕΒΛ࣮૷Ͱ͖Δ͔? • ίϯύΠϥج൫ (LLVMͳͲ) Λ௚઀࢖͏΂͖͔? • ʮ࣮ߦ࣌৘ใΛ࢖ͬͨΠϯϥΠϯԽʯ͸Ruby VMಛ༗ͷ໰୊Ͱ͋ΓɺίϯύΠϥج൫Λ௚઀࢖͏Ըܙ͸গͳ͍ • ΠϯϥΠϯԽʹݶΒͣɺݱঢ়͸͜ͷੈքͰղܾ͠ͳ͍ͱ͍͚ͳ͍໰୊͕େଟ਺

    • ΠϯϥΠϯԽͨ͠ޙͷ࠷దԽ͸CίϯύΠϥͰ΋ (ΠϯϥΠϯԽର৅ίʔυʹ޻෉ΛՃ͑Δ͜ͱͰ͋Δఔ౓͸) Մೳͩ͠ɺྫ͑͹LLVM PassύΠϓϥΠϯΛಠࣗʹ͍͔ͬͨ͡Βͱ͍ͬͯClangΑΓ੒ՌΛग़͢ͷ͸೉ͦ͠͏ • ༨ܭͳPassΛ࡟ͬͯίϯύΠϧ࣌ؒΛ୹͘͢Δͱ͔͸Ͱ͖Δ͔΋͠Εͳ͍͚Ͳɺ௕ظ࣮ߦϓϩάϥϜͰ͸ॏ ཁ౓͕௿͍ • CͰ΋ɺ͘͝ݶΒΕͨॏཁͳͱ͜ΖͰ͸ΠϯϥΠϯΞηϯϒϥΛ࢖͏ͱ͍͏બ୒ࢶ΋͋Δ (Ҡ২ίετʹ஫ҙ)
  25. ϩʔυϚοϓ

  26. ϩʔυϚοϓ: ݺͼग़͠ੑೳ perf-profile ISeq/ؔ਺ΛಡΉ଎౓ʹ ؔ܎͢ΔΠϕϯτͷௐࠪ objͷ௚઀ ϩʔυ࣮ݧ ඞͣ௨Δcall site ͳΔ΂͘ΠϯϥΠϯԽ

    so·ͱΊͯ Ϧϩʔυ perf-profile inline ूܭ ݺͼग़͕͠஗͘ ͳΔཧ༝ͷཧղ VM -> JIT callͰͷ Frame omission JITઐ༻fastpath JITઐ༻send໋ྩ
  27. ϩʔυϚοϓ: ΠϯϥΠϯԽ JIT: invokesuper Inline fastpath builtin method invokesuper inline

    cache JIT: Reconsider Inlining decision C method better fastpath JIT: C method Inline fastpath JIT: Inline getconstant JIT: C method Inline code JIT: Ruby method Frame omission JIT: C method Inline invoker JIT: C method Frame omission JIT: Inline attr_reader JIT: Inline attr_writer Better long-jump detection JIT: Pass args w/o VM stack JIT: ex-ivar inline invokesuper fastpath JIT: Ruby method Inline fastpath JIT: Unwrap vm_exec JIT: Ruby method Inline code JIT: ivar inline ex-ivar fastpath JIT: Support locals w/ frame omission leafify insns builtin attribute JIT: Inline from C method
  28. ϩʔυϚοϓ: ίʔυ࠷దԽ JIT: (very limited) Stack allocation JIT: Ruby locals

    -> C local var JIT: Reduce sp/pc access JIT: No-branch deoptimization JIT: Specialize opt_ for a type (very limited) Escase analysis JIT: Profile type in opt_ insns JIT -> VM On-Stack Replacement leafify insns Deoptimize on binding
  29. ϩʔυϚοϓ: ࠷దԽ • Inline invokesuper (patch) • header asetͷ࿩ɺsinatraͷϓϩϑΝΠϦϯάग़͢ •

    Inline Cʹ݁ہϒϩοΫ͞ΕΔ • Inline C method (committed) • downcaseͱ͔ͷ࿩ɺ͋ͱsettingsͷself.class (sinatraͷϓϩϑΝΠϦϯά·ͨग़͢) • invoker inlining • C definition inlining (ͱΓ͋͑ͣ .c Λ vm.c ʹ͚ͬͭͪ͘Ό͏࿩) • builtin attribute? (ϩʔυϚοϓʹ͍ΕΔ) => ΑΓଟ͘ΠϯϥΠϯԽରԠ • ࣮ݧͷޙɺ࣮૷Λݕ౼͍ͯ͠Δ࠷దԽ: • getconstant • attr reader inline • stack allocation • RubyϩʔΧϧม਺ͷCϩʔΧϧม਺མͱ͠ • On-Stack replacement • ΍Δͧͱ͍͏ؾ͕࣋ͪ͋Δ (ͱΓ͋͑ͣopt plus͋ͬͨΒinvalidateɺͱ͔) • ΠϯϥΠϯԽߦ͔Βnative pcͷਪఆͱVM pcͷ෮ݩ͸…·͋ઌͷ࿩Ͱ͍͍ͷͰ͸ • શ෦࣮ݧʹΑΔΠϯύΫτௐࠪ࣍ୈͰprioritize • JITࡁΈίʔυ͕ଟ͘ͳΔͱ஗͍໰୊ͷௐࠪ
  30. ϩʔυϚοϓ: ࠷దԽ • leafԽ • inlineԽ४උ → ΠϯϥΠϯԽ (C, super,

    attr reader) → getconstantΠϯϥΠϯԽ -> ؆қΤεέʔϓ ղੳ → ؆қstack allocation • inlining over loop • ࠷ޙ: GCC࠷దԽϑϨϯυϦͳؔ਺ʹมߋ => ͦͷઌ: LLVM͔ɺಠࣗIRίϯύΠϥ on Ractor • ผ໼ҹ͕ͩӈଆʹدͤͯ: on stack replacement • ಠཱ - ϝϞϦΞΫηε: single so ϩʔμ / JIT compaction → ஗͍ཧ༝ͷཧղͱରԠ → σΟεύον ߴ଎Խ • Ruby 2.7Ͱ͸σΟεύονΛ༏ઌ͕ͯͨ͠ɺ͜ͷઢ͸ఘΊͯͨ࿩ => Ͱ΋ղ͚Ε͹ϒϨʔΫεϧʔ
  31. ਐḿใࠂ

  32. ݱࡏͷঢ়گ: ~ 2.7

  33. ݱࡏͷঢ়گ: master

  34. ݱࡏͷঢ়گ: master 356e203a3a rb_funcall -> cd 88135845f1 (debug assertion) 9d3ffcfbfc

    (revert assertion) 7814b6c657 kwarg checks 46acd0075d builtin fb6a489af2 revert .: b9007b6c54 disposable cc 9511b4c8fa optimize cc ref 9e6e39c351 split ruby.h
  35. ࠷ۙͷ׆ಈ

  36. SEGVमਖ਼1: ίϯύΠϧ͞ΕͨελοΫϚγϯͷ෼ذमਖ਼ • ୯ʹYARVͷελοΫϚγϯ͕ͦͷ··ಈ͘Α͏ʹ࣮૷͢Δͱ஗͍ͷͰɺε λοΫͷࢀরΠϯσοΫε͕ఆ਺ʹͰ͖ΔΑ͏ίϯύΠϥ͕͕Μ͹͍ͬͯΔ ͕ɺͦͷ࣮૷෦෼Ͱͪΐͬͱόά͕͋Γຊདྷͱ͸ҧ͏ͱ͜Ζʹ෼ذ͞ΕΔ໰ ୊͕͋ͬͨ • 2020/2/18: https://github.com/ruby/ruby/commit/

    c4794ed73ad348a61a7cfbe3da0a7eb49ba46eb9
  37. SEGVमਖ਼2: ੜ੒ίʔυGC࣌ͷRoot FiberͷελοΫͷϚʔΫ࿙Ε • Fiber͔ΒσϑΥϧτεϨουʹ໭ΔͨΊʹσϑΥϧτͷεϨου΋Fiber૬౰ ͷߏ଄Λ͍࣋ͬͯΔ͕ɺ͔ͦ͜ΒผͷFiberʹελοΫ͕੾ΓସΘ͍ͬͯΔ ࣌ɺݱࡏ༗ޮͰͳ͍σϑΥϧτεϨουͷελοΫͰ࢖ΘΕ͍ͯΔίʔυͷ ϚʔΫ͕࿙Ε͍ͯͨ • 2020/2/28:

    https://github.com/ruby/ruby/commit/ adcf0316d1ecedae2a9157ad941550e0c0fb510b
  38. Disposable call-cache ͷมߋΛड͚ͨJITଆͷରԠ • Ractor (چGuild) ޲͚ʹϝιουΩϟογϡ͕immutableԽ [Feature #16614] ͞Εͨ

    ࣌ɺJITͷੜ੒ίʔυͰͷcacheͷࢀরʹؒ઀ࢀর͕ೖͬͨ • 2020/3/10: GC.compactରԠͷͨΊͷ෼ذΛɺJIT͕ݟ͍ͯΔcall-cache͕move͠ͳ ͍Α͏ʹͯ͠ରԠ https://github.com/ruby/ruby/commit/ 9511b4c8facf583073ed8ecfd3d84710565572a6 • GC࣌ʹJITͷੜ੒ίʔυ͕ࢀর͢Δcall-cacheΛద੾ʹϚʔΫ͢Δඞཁ͕͋ͬͨ • 2020/3/10: ݩͷ࣮૷ͷ࢓૊Έతͳόάͷमਖ਼ͱɺϝϞϦʔϦʔΫରԠ https:// github.com/ruby/ruby/commit/4bcd5981e80d3e1852c8723741a0069779464128 (ͳ͓͜ͷύον͸reallocͷ࢖͍ํ͕ؒҧ͍ͬͯΔ͕ɺOpenBSDͷ͓͔͛Ͱؾ෇͍ͨ)
  39. Disposable call-cache ͷมߋΛड͚ͨJITଆͷରԠ b9007b6c54 disposable cc 9511b4c8fa optimize cc ref

  40. super ͷ inline cache / fastpath • ݱࡏͷJITͷΠϯϥΠϯԽ͸VMͷinline cacheͰinvalidateΛߦͳ͏ͷͰɺsuper͕VMͷinline cacheʹରԠͯ͠ͳ͍ͱJITͷΠϯ

    ϥΠϯԽ͕Ͱ͖ͳ͍ • 2019/4/3: ॳରԠ (fastpath΋༗ޮԽ) https://github.com/ruby/ruby/commit/d147ad6231aebb1d478162fb8e109e0c6a696169 • VMͰςετ͸௨͚ͬͯͨͲ (ຊ౰͸4ͭόά͕͋Δ)ɺJIT͕SEGV͢ΔͷͰҰ୴Ϧόʔτ • 2020/2/12: ௐ͕ࠪ೉ߤͨ͠··์ஔ͍ͯͨ͠Βɺಉ͡มߋ͕ೖ͍ͬͯͨ https://github.com/ruby/ruby/pull/2869 • 2020/2/12: 4ͭͷόάͷ͏ͪ1ͭΛͩ͞͞͞Μ͕मਖ਼ • 2020/2/21: Disposable call-cache ͕ೖͬͨɻsuperͷinline cache͸࢒͕ͬͨfastpath͕͏͔ͬΓফ͑ͨ • fastpathʹΑΔ3ͭͷόάͱɺڪΒͦ͘Ε͕ݪҼͱࢥΘΕΔJITͷSEGV΋ফ͑ͨ • 2020/4/11: fastpathΛ࠶౓ಋೖɻrefinements޲͚ͷόά͸ରԠ͍ͯͨ͠ͷͰɺ3ͭͷ͏ͪ2ͭόά͕෮׆ • 2020/4/14: RailsͷCI͕མͪͨͱ͍͏yahonda͞ΜͷใࠂͰattr_writerͷsuper࣌ͷόάʹؾ෇͖ɺattr_readerͷํ΋मਖ਼ͨ͠ • Ruby 3Ͱ͸ (VMͰ΋) super͕଎͘ͳ͍ͬͯΔ͸ͣ!
  41. CͷϝιουͷΑΓਂ͍fastpath • ͋Δߦʹsplat args΍keyword args͕ͳ͍͜ͱ͸ίϯύΠϧ࣌ʹΘ͔Δ͕ɺ͜Ε·ͰͷfastpathͰ ͸ݺͼग़࣌͠ʹຖճνΣοΫ͞Ε͍ͯͨ • Ruby 2.7ͷ࣌ʹΩʔϫʔυҾ਺෼཭ͷͨΊʹগ͠஗͘ͳͬͨͱฉ͍͕ͨɺ͜͜ͷ෼ذ͕૿͑Δ ͱΩʔϫʔυҾ਺ͷ͋Γͳ͠ʹؔΘΒͣશCϝιουݺͼग़͠ʹӨڹ͕͋ΔͷͰɺ͜͜΋ؔ܎

    ͍͔ͯͨ͠΋ • 2020/4/13: CͷϝιουͷΠϯϥΠϯԽʹ޲͚ɺJITͰfastpathͷΠϯϥΠϯԽΛ։࢝ • 2020/4/13: JITͷΠϯϥΠϯԽίʔυʹ͜ΕΛؚΊͨ͘ͳ͔ͬͨͷͰɺ͜ͷνΣοΫΛεΩοϓ͢ ΔfastpathΛ༻ҙͯ͠ɺͦΕΛΠϯϥΠϯԽ͢ΔΑ͏ʹͨ͠ • CͰఆٛ͞Ε͍ͯͨΩʔϫʔυҾ਺͖ͭϝιου͸ɺ࠷ۙbuiltinͱ͍͏࢓૊ΈΛ࢖ͬͯRubyͰ࠶ ఆٛ͞ΕΔ܏޲ʹ͋ΔͷͰɺ͜ͷfastpathΛ௨Βͳ͍ϝιου͸ݮ͍ͬͯͦ͏
  42. DeoptimizationΛ࢖ͬͨJITͷleafԽ • VM໋ྩʹ͸leaf (೚ҙͷϝιουΛݺ͹ͳ͍) ͳ΋ͷͱͦ͏Ͱͳ͍΋ͷ͕͋Γɺओʹ returnʹ૬౰͢Δleave໋ྩ͸ׂΓࠐΈ͕ೖΔͱ೚ҙϝιουΛݺͿͨΊleafͰͳ͍ • leafͷ͔࣌͠VMͷpc΍spͷҠಈΛεΩοϓͰ͖ͳ͍ͷͰɺ୯ʹ return nil

    ͢Δ͚ͩ ͷϝιουͰ΋ (΄ͱΜͲͷ৔߹͸) ༨ܭͳϝϞϦΞΫηε͕͋ͬͨ • 2020/3/31: ׂΓࠐΈ͕͋Δ࣌͸VM࣮ߦʹϑΥʔϧόοΫ (Deoptimization) ͢Δ͜ ͱͰleafͱݟͳ͠ɺleave໋ྩʹ͓͚ΔpcͱspͷҠಈΛ΍Ίͨ • ͜ΕʹΑΓ return nil ͢Δ͚ͩͷϝιουͷωΠςΟϒίʔυ͸ɺׂΓࠐΈͷ νΣοΫͱnilΛฦ͢Ҏ֎ͷ༨ܭͳ໋ྩ͕શ͘ͳ͘ͳͬͨ
  43. Ex-ivar ͷ inline cache ରԠ • ;ͭ͏ͷΫϥε͸Ϋϥεͷߏ଄ମͷதʹΠϯελϯεม਺ͷຒΊࠐΈ͔ࢀরΛ͓࣋ͬͯΓɺΩϟογϡ͕ ώοτͨ͠৔߹ͷࢀর༻ίʔυͱcache invalidationͷίʔυ͚ͩJITͰ͸ੜ੒͠ɺinvalidate͞ΕͨΒΩϟ ϯηϧ͢ΔΑ͏ʹͳ͍ͬͯͨ

    • ͱ͜Ζ͕ɺHashΈ͍ͨͳҰ෦ͷΫϥεͰ͸ɺΠϯελϯεม਺࢖Θͳ͍Μ͡Όͳ͍͔ͱ͍͏Ծఆ͔Β͔Ϋ ϥεͷߏ଄ମ಺ʹͦΕ͕ͳ͘ɺάϩʔόϧͳϋογϡςʔϒϧ͔ΒΫϥε୯ҐͰࢀর͕อ࣋͞Ε͍ͯΔͨ ΊɺΠϯελϯεม਺ͷࢀরํ๏͕ҟͳΔ (exivar) • Railsʹ͸HashͷαϒΫϥε͕ແݶʹ͋Δ͠ɺͦ͜ͰΠϯελϯεม਺΋࢖͍ͬͯΔ • ͜Ε·Ͱ௨ৗͷivarʹಛԽͨ͠ίʔυΛੜ੒͍ͯͨ͠ͷͰɺexivarͷࢀর͕ൃੜͨ࣌͠͸JITΛΩϟϯη ϧ͍ͯͨ͠ • ͱΓ͋͑ͣivar޲͚ʹίϯύΠϧ͠ɺΩϟϯηϧ͞ΕͨΒexivar޲͚ʹ࠶ίϯύΠϧ͢Δײ͡ʹͨ͠ (ͦΕ ΋Ωϟϯηϧ͞ΕͨΒVMͱಉ࣮͡૷ʹͯ͠࠶ίϯύΠϧ)
  44. perf-profile • perf annotate͸CͷιʔεͷͲͷߦ͕஗͍͔ݟΑ͏ͱ͢Δͱɺasm͕ࠞͬͯ͟ෆ ศ • perf record --call-graph=dwarf ͔ΒಘΒΕΔtraceͱɺ࣮ࡍͷόΠφϦͷdwarf͔

    ΒಘΒΕΔ৘ใΛaggregate͠ɺCͷιʔεϕʔεͰϓϩϑΝΠϧ݁ՌΛදࣔ͢Δ • ͦ΋ͦ΋ಉ༷ͷػೳ͕OProfileʹ͸͋Δͷ͕ͩɺRubyͷJIT͕ಈతʹCͷίʔυΛ ు͍ͯϏϧυͯ͠ϩʔυ͢ΔΈ͍ͨͳෆࢥٞͳ͜ͱΛ΍͍ͬͯΔ͔Β͔JITੜ੒C ίʔυ͕͏·͘ಡΊͳ͔ͬͨͷͱɺperfͷํ͕৴༻ͯ͠Δ͠࢖͍׳ΕͯΔͷͰ perfϕʔεͰ΍Γ͔ͨͬͨ
  45. before: perf annotate

  46. after: perf-profile

  47. after: perf-profile • JITͰ஗͘ͳΔ৔߹ͷݪҼ΍ϗοτεϙοτͷղੳʹ׆༻ͨ͠Γ͠ͳ͔ͬͨΓ ͢Δ༧ఆ • traceʹ࢒ͬͯΔϑϨʔϜͷaggregate͸ಈ͍ͯΔ͕ɺͦͷϑϨʔϜͷΠϯϥ ΠϯԽݩ΋dwarfͷdebug_infoͷinlined_subroutineΛಡΊ͹Θ͔Δ͸ͣͳͷ ͰɺͦΕ΋ूܭʹؚΊ͍ͨͱࢥ͍ͬͯΔ (WIP)

  48. ϩʔυϚοϓͷঢ়گ

  49. ϩʔυϚοϓ: ݺͼग़͠ੑೳ perf-profile ISeq/ؔ਺ΛಡΉ଎౓ʹ ؔ܎͢ΔΠϕϯτͷௐࠪ objͷ௚઀ ϩʔυ࣮ݧ ඞͣ௨Δcall site ͳΔ΂͘ΠϯϥΠϯԽ

    so·ͱΊͯ Ϧϩʔυ perf-profile inline ूܭ ݺͼग़͕͠஗͘ ͳΔཧ༝ͷཧղ VM -> JIT callͰͷ Frame omission JITઐ༻fastpath JITઐ༻send໋ྩ
  50. ϩʔυϚοϓ: ݺͼग़͠ੑೳ perf-profile ISeq/ؔ਺ΛಡΉ଎౓ʹ ؔ܎͢ΔΠϕϯτͷௐࠪ objͷ௚઀ ϩʔυ࣮ݧ ඞͣ௨Δcall site ͳΔ΂͘ΠϯϥΠϯԽ

    so·ͱΊͯ Ϧϩʔυ perf-profile inline ूܭ ݺͼग़͕͠஗͘ ͳΔཧ༝ͷཧղ VM -> JIT callͰͷ Frame omission JITઐ༻fastpath JITઐ༻send໋ྩ ✅ ✅ ✅
  51. ϩʔυϚοϓ: ΠϯϥΠϯԽ JIT: invokesuper Inline fastpath builtin method invokesuper inline

    cache JIT: Reconsider Inlining decision C method better fastpath JIT: C method Inline fastpath JIT: Inline getconstant JIT: C method Inline code JIT: Ruby method Frame omission JIT: C method Inline invoker JIT: C method Frame omission JIT: Inline attr_reader JIT: Inline attr_writer Better long-jump detection JIT: Pass args w/o VM stack JIT: ex-ivar inline invokesuper fastpath JIT: Ruby method Inline fastpath JIT: Unwrap vm_exec JIT: Ruby method Inline code JIT: ivar inline ex-ivar fastpath JIT: Support locals w/ frame omission leafify insns builtin attribute JIT: Inline from C method
  52. ϩʔυϚοϓ: ΠϯϥΠϯԽ JIT: invokesuper Inline fastpath builtin method invokesuper inline

    cache JIT: Reconsider Inlining decision C method better fastpath JIT: C method Inline fastpath JIT: Inline getconstant JIT: C method Inline code JIT: Ruby method Frame omission JIT: C method Inline invoker JIT: C method Frame omission JIT: Inline attr_reader JIT: Inline attr_writer Better long-jump detection JIT: Pass args w/o VM stack JIT: ex-ivar inline invokesuper fastpath JIT: Ruby method Inline fastpath JIT: Unwrap vm_exec JIT: Ruby method Inline code JIT: ivar inline ex-ivar fastpath JIT: Support locals w/ frame omission leafify insns builtin attribute JIT: Inline from C method ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ⚠ ✅ ✅ ✅ ⚠
  53. ϩʔυϚοϓ: ίʔυ࠷దԽ JIT: (very limited) Stack allocation JIT: Ruby locals

    -> C local var JIT: Reduce sp/pc access JIT: No-branch deoptimization JIT: Specialize opt_ for a type (very limited) Escase analysis JIT: Profile type in opt_ insns JIT -> VM On-Stack Replacement leafify insns Deoptimize on binding
  54. ϩʔυϚοϓ: ίʔυ࠷దԽ JIT: (very limited) Stack allocation JIT: Ruby locals

    -> C local var JIT: Reduce sp/pc access JIT: No-branch deoptimization JIT: Specialize opt_ for a type (very limited) Escase analysis JIT: Profile type in opt_ insns JIT -> VM On-Stack Replacement leafify insns Deoptimize on binding ✅ ✅
  55. ·ͱΊ • ओʹίϯύΠϧ׬ྃޙͷ Sinatra / Rails ͷੑೳվળʹࠓ͸ूத͍ͯ͠Δ • ஗͘ͳΔ໰୊ͷௐࠪ͑͞͏·͍͚͘͹ɺ࣮༻తʹͳΔՄೳੑ͸ߴ͍ •

    ߏ૝͍ͯͨ͠࠷దԽʹඞཁͳ४උΛணʑͱਐΊ͓ͯΓɺ࣮ݧͰޮՌ͕֬ೝͰ ͖ͨ΋ͷ͔Β Ruby 3 ʹ௥Ճ༧ఆ