$30 off During Our Annual Pro Sale. View Details »

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

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

Takashi Kokubun

April 16, 2020
Tweet

More Decks by Takashi Kokubun

Other Decks in Programming

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.

    View Slide


  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ͷੑೳվળ

    View Slide

  3. ࠓ೔࿩͢͜ͱ
    • Ruby 3ʹ͓͚ΔJITͷΰʔϧ
    • ੑೳܭଌํ๏ͷ෼ྨ
    • ϕϯνϚʔΫ໨ඪ
    • ໨ඪୡ੒ͷͨΊͷઓུ
    • جຊํ਑
    • ϩʔυϚοϓ
    • ਐḿใࠂ
    • ࠷ۙͷ׆ಈ
    • ϩʔυϚοϓͷঢ়گ

    View Slide

  4. ࠓ೔࿩͞ͳ͍͜ͱ
    • RubyͷJIT͕ͲͷΑ͏ͳΞʔΩςΫνϟͳͷ͔
    • ϒϩά: https://k0kubun.hatenablog.com/entry/ruby26-jit
    • աڈͷൃදࢿྉ: https://speakerdeck.com/k0kubun

    View Slide

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

    View Slide

  6. Ruby 3ʹ͓͚ΔJITͷΰʔϧ
    • Ruby 3x3: Ruby 3 ͸ Ruby 2.0 ͷ3ഒߴ଎Խ
    • ͲͷΑ͏ͳܭଌํ๏ͱϕϯνͰ໨ඪΛઃఆ͢Δ͔?

    View Slide

  7. ੑೳܭଌํ๏ͷ෼ྨ

    View Slide

  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ϩοΫ, εϨου΍ϓϩηε

    View Slide

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

    View Slide

  10. ϕϯνϚʔΫ໨ඪ

    View Slide

  11. RubyॲཧܥͷϚΫϩͳϕϯνϚʔΫ
    • mame/optcarrot - RubyͷϕϯνϚʔΫ༻ʹ࡞ΒΕͨNESΤϛϡϨʔλ
    • benchmark-driver/sinatra - SinatraͰݻఆͷจࣈྻϨεϙϯεΛฦ͢
    • k0kubun/railsbench - Railsͷ #show ΞΫγϣϯͷscaffold࣮૷
    • noahgibbs/rsb - DiscourseΑΓγϯϓϧͱ͞Ε͍ͯΔRailsͷϕϯν
    • discourse/discourse - ϕϯνΛ࣋ͭ ϦΞϧϫʔϧυRailsΞϓϦέʔγϣϯ

    View Slide

  12. RubyॲཧܥͷϚΫϩͳϕϯνϚʔΫ
    • ଟ͘ͷϕϯνͰݱࡏվળର৅ʹ͍ͯ͠Δείʔϓ: Level 1~2
    • Rails΍SinatraͷϕϯνͰ͸Level 1Ͱ΋ݱঢ়͋·Γ͕ࠩग़͍ͤͯͳ͍
    • ੜ੒ίʔυͷੑೳͱແؔ܎ʹɺJITίϯύΠϧࡁΈϝιου͕૿͑Δ΄ͲͲ͏ͯ͠΋஗
    ͘ͳΔ໰୊(ޙड़)͕͋ΓɺLevel 2Ҏ্͸શͯͦΕͷ͍ͤͰ஗͍ (Α͏ʹݟ͑Δ)
    • OptcarrotϕϯνͰͷܭଌํ๏: Level 4
    • ϑΣΞʹଞ࣮૷ͱൺֱΛߦͳ͏ʹ͸ݩͷϨΪϡϨʔγϣϯʹԊ͏Ҏ֎ͳ͍ͷͰ͜͏ͳΔ
    • Level 4Ͱ΋े෼վળͰ͖͍ͯΔ͕ɺܧଓతͳੑೳվળͷνΣοΫʹ͸ຊ౰͸Level 2~3
    ΛݟΔ΂͖

    View Slide

  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

    View Slide

  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

    View Slide

  15. ໨ඪୡ੒ͷͨΊͷઓུ

    View Slide

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

    View Slide

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

    View Slide

  18. ໰୊1: JITੜ੒ίʔυݺͼग़͠ͷεέʔϥϏϦςΟ
    • nilΛฦ͚ͩ͢ͷϝιουΛ100ݸ࡞ͬͯॱ൪ʹݺͼग़͍ͯ͘͠ͱɺ1ݸΛಉ͡ճ਺ݺͿͷʹൺ΂ͯJITࡁΈͷ৔߹ͱͯ΋஗͘ͳΔ
    • nilΛฦ࣮͢૷ͱ͔஗͘͠Α͏͕ͳ͍
    • ΞηϯϒϥΛோΊɺRuby 3 Ͱ͸༨ܭͳ໋ྩΛશͯ࡟ͬͨ (ޙड़) ͕ɺผʹ͜Ε͸௚Βͳ͍
    • ϩʔυํ๏ʹΑΔΠϯύΫτ͸͕͋ͬͨɺ͜Ε͸ՄೳͳݶΓվળͨ͠
    • શ෦ίϯύΠϧ͠ऴΘͬͨΒશϝιουΛҰͭͷsoϑΝΠϧʹ·ͱΊͯશϦϩʔυ͍ͯ͠Δ
    • shinh͞Μ͕ॻ͍ͨobjϑΝΠϧϩʔμͱ΄΅ಉ͡ੑೳ͕ग़͍ͯΔͷͰɺଟ෼໰୊͸͜͜Ͱ͸ͳ͍
    • Ͱ͸Կ͕஗͍ͷ͔?
    • ͓ͦΒ͘: όΠτίʔυΛ๊͑Δߏ଄ମΛಡΉͷ͕ແବʹ2Օॴ͋Δ + ੜ੒ίʔυͦͷ΋ͷͷϩʔυ͕Ωϟογϡ͔ΒᷓΕΔ
    • ͨͩ͠໌֬ͳࠜڌ͕ݟ͚ͭΒΕ͓ͯΒͣɺͲ͜ΛͲ͏௚͢΂͖͔ͷ֬ূ͕ಘΒΕ͍ͯͳ͍ (ຊ౰ʹ͜Ε͕ϘτϧωοΫͳͷ
    ͔͢Β໌֬Ͱ͸ͳ͍)

    View Slide

  19. ໰୊1ͷΞϓϩʔν
    • ·ͣ͜Ε͕Ͳͷఔ౓໰୊ʹͳ͍ͬͯΔ͔Λ໌֬ʹ೺Ѳ͢Δ:
    • શମͰͷӨڹ֬ೝʹ͸ޙड़ͷperf-profileΛࢼ͢
    • खݩͷϚγϯͰϝϞϦ΍CPUͷΩϟογϡͷΞΫηεʹԿns͔͔Δ͔֬ೝ͠ɺͦΕ͕ͲͷՕॴͰԿճى͖͍ͯΔ͔Λperfͷevent
    ͰݟͯΈΔ
    • όΠτίʔυΛ๊͑Δߏ଄ମΛಡΉͷ͕ແବʹ2Օॴ͋Δ:
    • ଟ෼Ͳ͏ʹ͔Ͱ͖Δ (͕ɺຊ౰ʹ͜Ε͕ϘτϧωοΫʹͳΔ͔?)
    • Ruby 2.7ͷ࣌ʹॻ͍ͨύον΋͋Δ͕ɺͦΕ͸VMͷํʹΠϯύΫτ͕͋Δͷ͕ཁमਖ਼
    • ੜ੒ίʔυͦͷ΋ͷͷϩʔυ͕Ωϟογϡ͔ΒᷓΕΔ:
    • ؔ਺ϙΠϯλΛܦ༝ͨ͠ݺͼग़͠ͷ਺Λ2͔ͭΒ1ͭʹ·ͱΊΔ͜ͱ͸Մೳ
    • Ruby 2.7ͷ࣌ͦΕΛ࣮ݧ͕ͨ͠ɺSinatra / RailsͷϕϯνʹޮՌ͕ͳ͘ɺղܾํ๏ͷਖ਼͠͞ʹ֬ূ͕ͳ͍ (ͳͷͰ໰୊ͷৄࡉௐࠪʹ
    ϒϩοΫ͞ΕΔ)
    • ؔઅݺͼग़͠Λ1͔Β0·ͰݮΒ͢ʹ͸ɺΠϯϥΠϯԽ͕࢖͑Δ͔΋

    View Slide

  20. ໰୊2: ΠϯϥΠϯԽՄೳͳൣғ͕ݶΒΕ͍ͯΔ
    • Rubyͷϝιουݺͼग़͠ͷΠϯϥΠϯԽ͸Ruby 2.7Ͱೖͬͨ
    • ͨͩ͠ΠϯϥΠϯԽ͢ΔͱOptcarrotͷfps͕མͪΔ܏޲ʹ͋Γ(ίϯύΠϧ࣌ؒ΁ͷӨڹ͔ɺίʔυαΠζ
    ͷ໰୊͔)ɺ΄ͱΜͲ࢖ΘΕͳ͍ঢ়ଶʹͯ͋͠Δ
    • ͦΕ͔ΒɺϑϨʔϜͷpush/pop΋࡟ΔΠϯϥΠϯԽ͕Ͱ͖Δ৚݅͸·͔ͩͳΓݶΓ͕͋Δ (ϩʔΧϧม਺ʹ
    ·ͩରԠͯ͠ͳ͍ɺͳͲ)
    • ࠶ؼ͢Δ৔߹ʹࣗ਎ͷωΠςΟϒؔ਺Λݺͼग़ౕ͢΋લೖΕ͍͕ͯͨɺόάͬͯrevert
    • Rubyͷϝιουͷsuper΍yield͸·ͨผͷέΞ͕ඞཁ
    • CͷϝιουͷΠϯϥΠϯԽ͸·ͩೖ͍ͬͯͳ͍
    • ͜Εͷ४උʹඞཁͳ࢓૊ΈΛ͍ΕΔͱOptcarrotͷfps͕མͪΔ໰୊͕͋ͬͨ
    • attr_readerͷΠϯϥΠϯԽΛ͔ͳΓલʹೖΕ͍͕ͯͨɺόάͬͯrevert

    View Slide

  21. ໰୊2ͷΞϓϩʔν
    • ࣮૷͸ຊ࣭తʹ͸೉͘͠ͳ͍
    • όάͰSEGVΛ1ͭੜΉ͝ͱʹҰ൩͔Β਺೔ফ໓͢Δͱ͍͏໰୊͸͋Δ
    • ΠϯϥΠϯԽ͢Δʹ͸͠͹͠͹࣮૷Λॏෳͤ͞Δඞཁ͕͋Δ͕:
    • ՄೳͳݶΓVMͱ࣮૷Λڞ༗Ͱ͖ΔΑ͏ؔ਺ʹڞ௨෦෼Λ੾Γग़͢
    • ͦ΋ͦ΋ΠϯϥΠϯԽ͠ͳ͍ͱ͍͚ͳ͍είʔϓΛ࠷ॳ͔ΒॖΊͯ͠·͏ͨΊʹɺ"fastpath" ͱ͍͏
    ػߏΛ࢖͏
    • fastpath: ϝιουσΟεύον͸ؔ਺ϙΠϯλΛܦ༝ͯ͠ߦͳΘΕΔ͕ɺ࠷దԽՄೳͳ࣌ʹؔ਺ϙ
    Πϯλͱͯ͠ηοτ͞ΕΔΑΓγϯϓϧͳύε͕fastpath
    • JITͰͷΈ࣮૷είʔϓΛڱΊΔͱಉ͡ڍಈ͕ςετ͞ΕΔػձ͕গͳ͘όάΓ΍͘͢ͳΔ͠ɺ͍ͭ
    ͷ·ʹ͔VMͱ࣮૷͕ဃ཭͠΍͍͢

    View Slide

  22. ໰୊1ͱ໰୊2ͷ࣍͸…?
    • ໰୊1Λղ͍ͯ΋ɺ஗͘ͳΒͳ͘ͳΔ͚ͩͰɺ୯ಠͰ͸໨ඪୡ੒ʹͳΒͳ͍
    • ໰୊2Λ΍Δͱɺ࢓૊Έ্CίϯύΠϥ͕͋Δఔ౓଎͘͸ͯ͘͠ΕΔ͕ɺΠϯ
    ϥΠϯԽͦͷ΋ͷ͸ຊ࣭తʹ͸࠷దԽͰ͸ͳ͍
    • ΑΓ଎͍ͯ͘͘͠ʹ͸ɺͲΜͲΜ࠷దԽΛ଍͍ͯ͘͠ඞཁ͕͋Δ

    View Slide

  23. ޮՌ͕ߴ͍ͱࢥΘΕΔ࠷దԽ
    • ࣮ߦ࣌৘ใΛ࢖ͬͨΠϯϥΠϯԽͱɺ࣮૷ͷ୯७ԽΛ܁Γฦ͢
    • Constant folding
    • Dead code elimination
    • Loop-invariant code motion
    • ϝϞϦΞΫηεͷ࠷దԽ
    • ώʔϓ > ελοΫ > Ϩδελ > ଈ஋

    View Slide

  24. RubyͷJITͷ࢓૊ΈͰͦΕΒΛ࣮૷Ͱ͖Δ͔?
    • ίϯύΠϥج൫ (LLVMͳͲ) Λ௚઀࢖͏΂͖͔?
    • ʮ࣮ߦ࣌৘ใΛ࢖ͬͨΠϯϥΠϯԽʯ͸Ruby VMಛ༗ͷ໰୊Ͱ͋ΓɺίϯύΠϥج൫Λ௚઀࢖͏Ըܙ͸গͳ͍
    • ΠϯϥΠϯԽʹݶΒͣɺݱঢ়͸͜ͷੈքͰղܾ͠ͳ͍ͱ͍͚ͳ͍໰୊͕େଟ਺
    • ΠϯϥΠϯԽͨ͠ޙͷ࠷దԽ͸CίϯύΠϥͰ΋ (ΠϯϥΠϯԽର৅ίʔυʹ޻෉ΛՃ͑Δ͜ͱͰ͋Δఔ౓͸)
    Մೳͩ͠ɺྫ͑͹LLVM PassύΠϓϥΠϯΛಠࣗʹ͍͔ͬͨ͡Βͱ͍ͬͯClangΑΓ੒ՌΛग़͢ͷ͸೉ͦ͠͏
    • ༨ܭͳPassΛ࡟ͬͯίϯύΠϧ࣌ؒΛ୹͘͢Δͱ͔͸Ͱ͖Δ͔΋͠Εͳ͍͚Ͳɺ௕ظ࣮ߦϓϩάϥϜͰ͸ॏ
    ཁ౓͕௿͍
    • CͰ΋ɺ͘͝ݶΒΕͨॏཁͳͱ͜ΖͰ͸ΠϯϥΠϯΞηϯϒϥΛ࢖͏ͱ͍͏બ୒ࢶ΋͋Δ (Ҡ২ίετʹ஫ҙ)

    View Slide

  25. ϩʔυϚοϓ

    View Slide

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

    View Slide

  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

    View Slide

  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

    View Slide

  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ࡁΈίʔυ͕ଟ͘ͳΔͱ஗͍໰୊ͷௐࠪ

    View Slide

  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Ͱ͸σΟεύονΛ༏ઌ͕ͯͨ͠ɺ͜ͷઢ͸ఘΊͯͨ࿩ => Ͱ΋ղ͚Ε͹ϒϨʔΫεϧʔ

    View Slide

  31. ਐḿใࠂ

    View Slide

  32. ݱࡏͷঢ়گ: ~ 2.7

    View Slide

  33. ݱࡏͷঢ়گ: master

    View Slide

  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

    View Slide

  35. ࠷ۙͷ׆ಈ

    View Slide

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

    View Slide

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

    View Slide

  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ͷ͓͔͛Ͱؾ෇͍ͨ)

    View Slide

  39. Disposable call-cache ͷมߋΛड͚ͨJITଆͷରԠ
    b9007b6c54
    disposable cc
    9511b4c8fa
    optimize cc ref

    View Slide

  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͕଎͘ͳ͍ͬͯΔ͸ͣ!

    View Slide

  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Λ௨Βͳ͍ϝιου͸ݮ͍ͬͯͦ͏

    View Slide

  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Λฦ͢Ҏ֎ͷ༨ܭͳ໋ྩ͕શ͘ͳ͘ͳͬͨ

    View Slide

  43. Ex-ivar ͷ inline cache ରԠ
    • ;ͭ͏ͷΫϥε͸Ϋϥεͷߏ଄ମͷதʹΠϯελϯεม਺ͷຒΊࠐΈ͔ࢀরΛ͓࣋ͬͯΓɺΩϟογϡ͕
    ώοτͨ͠৔߹ͷࢀর༻ίʔυͱcache invalidationͷίʔυ͚ͩJITͰ͸ੜ੒͠ɺinvalidate͞ΕͨΒΩϟ
    ϯηϧ͢ΔΑ͏ʹͳ͍ͬͯͨ
    • ͱ͜Ζ͕ɺHashΈ͍ͨͳҰ෦ͷΫϥεͰ͸ɺΠϯελϯεม਺࢖Θͳ͍Μ͡Όͳ͍͔ͱ͍͏Ծఆ͔Β͔Ϋ
    ϥεͷߏ଄ମ಺ʹͦΕ͕ͳ͘ɺάϩʔόϧͳϋογϡςʔϒϧ͔ΒΫϥε୯ҐͰࢀর͕อ࣋͞Ε͍ͯΔͨ
    ΊɺΠϯελϯεม਺ͷࢀরํ๏͕ҟͳΔ (exivar)
    • Railsʹ͸HashͷαϒΫϥε͕ແݶʹ͋Δ͠ɺͦ͜ͰΠϯελϯεม਺΋࢖͍ͬͯΔ
    • ͜Ε·Ͱ௨ৗͷivarʹಛԽͨ͠ίʔυΛੜ੒͍ͯͨ͠ͷͰɺexivarͷࢀর͕ൃੜͨ࣌͠͸JITΛΩϟϯη
    ϧ͍ͯͨ͠
    • ͱΓ͋͑ͣivar޲͚ʹίϯύΠϧ͠ɺΩϟϯηϧ͞ΕͨΒexivar޲͚ʹ࠶ίϯύΠϧ͢Δײ͡ʹͨ͠ (ͦΕ
    ΋Ωϟϯηϧ͞ΕͨΒVMͱಉ࣮͡૷ʹͯ͠࠶ίϯύΠϧ)

    View Slide

  44. perf-profile
    • perf annotate͸CͷιʔεͷͲͷߦ͕஗͍͔ݟΑ͏ͱ͢Δͱɺasm͕ࠞͬͯ͟ෆ

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

    View Slide

  45. before: perf annotate

    View Slide

  46. after: perf-profile

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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





    View Slide

  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

    View Slide

  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








    ✅ ✅ ⚠

    ✅ ✅




    View Slide

  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

    View Slide

  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
    ✅ ✅





    View Slide

  55. ·ͱΊ
    • ओʹίϯύΠϧ׬ྃޙͷ Sinatra / Rails ͷੑೳվળʹࠓ͸ूத͍ͯ͠Δ
    • ஗͘ͳΔ໰୊ͷௐࠪ͑͞͏·͍͚͘͹ɺ࣮༻తʹͳΔՄೳੑ͸ߴ͍
    • ߏ૝͍ͯͨ͠࠷దԽʹඞཁͳ४උΛணʑͱਐΊ͓ͯΓɺ࣮ݧͰޮՌ͕֬ೝͰ
    ͖ͨ΋ͷ͔Β Ruby 3 ʹ௥Ճ༧ఆ

    View Slide