Slide 1

Slide 1 text

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.

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

Ruby 3ʹ͓͚Δ JITͷΰʔϧ

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

ੑೳܭଌํ๏ͷ෼ྨ

Slide 8

Slide 8 text

ੑೳܭଌํ๏ͷ෼ྨ • 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ϩοΫ, εϨου΍ϓϩηε

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

ϕϯνϚʔΫ໨ඪ

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

ϕϯνϚʔΫ໨ඪ 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

Slide 14

Slide 14 text

ϕϯνϚʔΫ໨ඪ 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 ✅

Slide 15

Slide 15 text

໨ඪୡ੒ͷͨΊͷઓུ

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

ϩʔυϚοϓ

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

ϩʔυϚοϓ: ΠϯϥΠϯԽ 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

Slide 28

Slide 28 text

ϩʔυϚοϓ: ίʔυ࠷దԽ 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

Slide 29

Slide 29 text

ϩʔυϚοϓ: ࠷దԽ • 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ࡁΈίʔυ͕ଟ͘ͳΔͱ஗͍໰୊ͷௐࠪ

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

ਐḿใࠂ

Slide 32

Slide 32 text

ݱࡏͷঢ়گ: ~ 2.7

Slide 33

Slide 33 text

ݱࡏͷঢ়گ: master

Slide 34

Slide 34 text

ݱࡏͷঢ়گ: 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

Slide 35

Slide 35 text

࠷ۙͷ׆ಈ

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

before: perf annotate

Slide 46

Slide 46 text

after: perf-profile

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

ϩʔυϚοϓͷঢ়گ

Slide 49

Slide 49 text

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

Slide 50

Slide 50 text

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

Slide 51

Slide 51 text

ϩʔυϚοϓ: ΠϯϥΠϯԽ 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

Slide 52

Slide 52 text

ϩʔυϚοϓ: ΠϯϥΠϯԽ 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 ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ⚠ ✅ ✅ ✅ ⚠

Slide 53

Slide 53 text

ϩʔυϚοϓ: ίʔυ࠷దԽ 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

Slide 54

Slide 54 text

ϩʔυϚοϓ: ίʔυ࠷దԽ 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 ✅ ✅

Slide 55

Slide 55 text

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