Slide 1

Slide 1 text

༗༑ େี (osyoyu) | Ruby Association Activity Report 2024/7/19 Rubyͷ ύϑΥʔϚϯεϓϩϑΝΠϦϯάͷվળ

Slide 2

Slide 2 text

pp self (ࣗݾ঺հ) • ༗༑ େี (Daisuke Aritomo) • github.com/osyoyu ͳͲ • גࣜձࣾεϚʔτόϯΫۈ຿

Slide 3

Slide 3 text

ϓϩδΣΫτ ʮRubyͷύϑΥʔϚϯεϓϩϑΝΠϦϯάͷվળʯ ʹ͍ͭͯ

Slide 4

Slide 4 text

ύϑΥʔϚϯεϓϩϑΝΠϦϯάͱ͸ • ϓϩάϥϜͷੑೳͷνϡʔχϯάΛ͢ΔͨΊʹ • ʮϓϩϑΝΠϥʯΛ࢖ͬͯɺϓϩάϥϜͷ࣮ߦΛৄࡉʹ؍࡯͢Δ͜ͱ • ߴ଎Խɾ࠷దԽͷώϯτʹ͢Δ • e.g. "WebΞϓϦέʔγϣϯ͸SQLͷ࣮ߦ଴͕ͪେ൒" ͬͯຊ౰? • CPUϓϩϑΝΠϥ = ؔ਺ɾϝιου୯ҐͰͷ࣮ߦ࣌ؒΛܭଌ • ώʔϓϓϩϑΝΠϥ = ώʔϓϝϞϦͷར༻ঢ়گΛܭଌ

Slide 5

Slide 5 text

RubyϓϩϑΝΠϥͷݱگ (2023) StackProf Sampling In-Process rb_pro fi le_frames() ௿Φʔόʔϔου ΞΫςΟϒͳεϨουͷΈΛ؍࡯Մೳ ruby-prof Tracing In-Process TracePoint ͢΂ͯͷϝιουݺͼग़͠Λਖ਼֬ʹ௥੻Մ ߴΦʔόʔϔου rbspy Sampling Out-of-Process process_vm_readv(2) ϓϩάϥϜͷมߋͳ͠ͰಋೖՄೳ RubyͷόʔδϣϯʹରԠͨ͠΋ͷ͕ඞཁ • ޿͘࢖ΘΕΔϓϩϑΝΠϥ͕͍͔ͭ͘ଘࡏ͢Δ • ͦΕͧΕͷಛ௃͕͋ΓɺͲΕ͕࠷΋͙͢Ε͍ͯΔͱ͍͏΋ͷͰ͸ͳ͍ • (ࠓճͷϓϩδΣΫτͰ͸CPUϓϩϑΝΠϥʹߜͬͯௐࠪ)

Slide 6

Slide 6 text

RubyϓϩϑΝΠϥͷݱگ (2023) Sampling Tracing ҰఆͷपظͰαϯϓϧΛऔಘ͢Δɺ౷ܭతͳख๏ 👍 Low overhead / 👎 ৴པੑ͸ྼΔ શϝιουΤϯτϦʔͱϦλʔϯΛه࿥͢Δ 👍 ৴པੑ͸࣮֬ / 👎 High overhead In-Process Out-of-Process Rubyϓϩηε಺ʹϓϩϑΝΠϥΛઃஔ͢Δख๏ 👍 ॲཧܥʹؔ͢Δଟ༷ͳ৘ใΛऔಘՄ 👎 ಋೖ͕ෳࡶʹͳΓ͕ͪ ϓϩηε֎͔ΒϝϞϦಡΈऔΓ౳Ͱ৘ใΛऔಘ 👍 ಋೖɾ࢖͍ํ͕γϯϓϧ 👎 ࢓૊Έͱͯ͠ෳࡶɺॲཧܥ΁ͷ௥ै͕େม StackProf Sampling In-Process rb_pro fi le_frames() ௿Φʔόʔϔου ΞΫςΟϒͳεϨουͷΈΛ؍࡯Մೳ ruby-prof Tracing In-Process TracePoint ͢΂ͯͷϝιουݺͼग़͠Λਖ਼֬ʹ௥੻Մ ߴΦʔόʔϔου rbspy Sampling Out-of-Process process_vm_readv(2) ϓϩάϥϜͷมߋͳ͠ͰಋೖՄೳ RubyͷόʔδϣϯʹରԠͨ͠΋ͷ͕ඞཁ

Slide 7

Slide 7 text

ϓϩδΣΫτͷΰʔϧઃఆ RubyҎ֎ͷݴޠॲཧܥͷϓϩϑΝΠϥΛ؍࡯ • Go (pprof) ΍ Java (JFR, async-pro fi le, ...) ͷΤίγεςϜ͕ඇৗʹॆ࣮ • ݴޠػೳʹ͋Θͤͨػೳ͕ॆ࣮͍ͯ͠Δ • ಛʹ pprof (Go) ͸಄ͻͱͭൈ͚͍ͯΔ • Xcode, Android Studio ૊ΈࠐΈͷϓϩϑΝΠϥ΋ۃΊͯڧྗ • CPU, Memory, Network, Battery, Events, શ෦·ͱΊͯݟΒΕΔ → Ruby ͷಛੑΛΑΓ౿·͑ͨϓϩϑΝΠϦϯάΛՄೳʹ͍ͨ͠

Slide 8

Slide 8 text

ϓϩδΣΫτͷΰʔϧઃఆ RubyͷಛੑΛ౿·͑ͨϓϩϑΝΠϧΛͰ͖Δ͜ͱ - RubyεϨου୯ҐͰͷ݁ՌΛग़ྗͰ͖Δ - RubyҎ֎ͷ෦෼ (C) ΛϒϥοΫϘοΫεʹ͠ͳ͍ - Global VM Lock (GVL) ͷӨڹΛܭଌͰ͖Δ ͙͢ΕͨϏδϡΞϥΠζΛ௨ͨ͠෼ੳΛՄೳʹ͢Δ͜ͱ - ෼ੳʹ༗༻ͳࢹ఺Λఏڙ͢Δ ҎԼͷੑ࣭Λͦͳ࣮͑ͨݧతͳϓϩϑΝΠϥΛ࣮૷͢Δɻ ·ͨɺ͜ΕΒͷ੒ՌΛRubyΤίγεςϜʹؐݩ͢Δɻ

Slide 9

Slide 9 text

ϓϩδΣΫτͷ੒Ռ: Pf2 ϓϩϑΝΠϥ

Slide 10

Slide 10 text

ϓϩδΣΫτͷ੒Ռ෺ Pf2ϓϩϑΝΠϥ github.com/osyoyu/pf2 ௐࠪɾ࣮૷ࢿྉͷScrapbox scrapbox.com/pf2

Slide 11

Slide 11 text

ϓϩδΣΫτͷ੒Ռ෺ The depths of profiling Ruby Daisuke Aritomo (@osyoyu) RubyKaigi 2024Ͱͷൃද "The depths of pro fi ling Ruby"

Slide 12

Slide 12 text

Pf2 ϓϩϑΝΠϥ • Rubyͷ "۱ʑ·Ͱ" "ਖ਼֬ʹ" ଌఆ Ͱ͖Δ͜ͱΛ໨ࢦ͢ • RubyϑϨʔϜ • C (Native) ϑϨʔϜ • GVLͷ઎༗ঢ়گ • Sampling, In-process ͳϓϩϑΝΠϥ ͱͯ͠ઃܭ • ͙͢ΕͨϏδϡΞϥΠζ΋ͦͳ͑Δ

Slide 13

Slide 13 text

࢖͍͔ͨ % bundle exec pf2 run -- ruby main.rb [Pf2] Listening on localhost:51502. [Pf2] Open https://profiler.firefox.com/from-url/ http%3A%2F%2Flocalhost%3A51502%2Fprofile for visualization. Pf2.profile(mode: :wall) { # code to be profiled fib(200) } ίϚϯυϥΠϯ͔Β ruby શମΛϓϩϑΝΠϧ ϓϩάϥϜͷҰ෦͚ͩΛϓϩϑΝΠϧ

Slide 14

Slide 14 text

ϏδϡΞϥΠζ εϨου͝ͱͷ༷ࢠͷ τϥοΫ ίʔϧπϦʔ Flamegraph

Slide 15

Slide 15 text

Firefox Profilerͷར༻ • ϏδϡΞϥΠζ͸ॏཁͳػೳ͕ͩɺͦΕࣗମͰ1ϓϩδΣΫτʹͳΔ΄Ͳେ͖͍ • ຊϓϩδΣΫτͰ͸ɺ׬੒౓ͷߴ͍طଘͷϏδϡΞϥΠβ = Firefox Pro fi lerʹ RubyͷཁૉΛϚοϐϯά͢Δ͜ͱͰରԠ • Firefox Pro fi lerͷϓϩϑΝΠϥػೳ͸·ͬͨ͘࢖͍ͬͯͳ͍ ϓϩϑΝΠϧσʔλࣗମ͸ Firefox Pro fi ler ʹඇґଘɻ ଞͷϏδϡΞϥΠβʢgo tool pprofʣʹ΋ରԠ

Slide 16

Slide 16 text

ϏδϡΞϥΠζ? • εϨου୯ҐͰͷGVLͷ઎༗཰ͷ ෼ੳϏϡʔ΋ఏڙ • puma ͳͲͰͷεϨου਺ͷௐ੔ʹ ༗༻

Slide 17

Slide 17 text

[σϞ] Optcarrot % pf2 run -- bin/optcarrot 'examples/Lan Master.zip' [Pf2] Listening on localhost:51502. [Pf2] Open https://profiler.firefox.com/from-url/ http%3A%2F%2Flocalhost%3A51502%2Fprofile for visualization.

Slide 18

Slide 18 text

[σϞ] Multi-threaded Mandelbrot "Mandelbrot set" by Wolfgang Beyer. Licensed under CC BY-SA 3.0 https://creativecommons.org/licenses/by-sa/3.0/ • Ϛϯσϧϒϩू߹ = ਺ࣜʹΑͬͯఆٛ͞ΕΔ • Ϛϯσϧϒϩू߹Λܭࢉ͠ɺࠨਤΛϓϩοτ ͢ΔϓϩάϥϜΛϓϩϑΝΠϧ • ฒྻԽ͕Α͘ޮ͘΋ͷͱͯ͠஌ΒΕΔ • ͜͜Ͱ͸16 threadsͰܭࢉ

Slide 19

Slide 19 text

No content

Slide 20

Slide 20 text

[σϞ] Rails (osyoyu.com/blog) https://pro fi ler. fi refox.com/from-url/https%3A%2F%2Fosyoyu-pf2prof.s3.ap- northeast-1.amazonaws.com%2Fincunabula-latest. fi refoxpro fi ler.json/calltree/?v=10 osyoyu.com/blog ͷ3ඵ͝ͱʹߋ৽͞ΕΔϓϩϑΝΠϧΛެ։த

Slide 21

Slide 21 text

No content

Slide 22

Slide 22 text

[σϞ] Optcarrot with C frames

Slide 23

Slide 23 text

Pf2ͷ࢓૊Έͷུ֓ αϯϓϧͷऩू ҰఆपظͰϓϩάϥϜͷ࣮ߦঢ়گΛऔಘ ूܭ ؔ਺໊ͷ෮ݩͳͲ ϏδϡΞϥΠζ Call tree΍ fl amegraphͳͲͷ෼͔Γ΍͍͢දݱ΁ • Ұఆ࣌ؒ͝ͱʹ • RubyͷελοΫͱ • CͷελοΫΛऩू • ϝϞϦ্ʹอଘ • σϑΥϧτͷपظ͸9ms

Slide 24

Slide 24 text

Pf2ͷ࢓૊Έͷུ֓ αϯϓϧͷऩू ҰఆपظͰϓϩάϥϜͷ࣮ߦঢ়گΛऔಘ ूܭ ؔ਺໊ͷ෮ݩͳͲ ϏδϡΞϥΠζ Call tree΍ fl amegraphͳͲͷ෼͔Γ΍͍͢දݱ΁ • ऩूͨ͠αϯϓϧΛूܭ͠ɺ ग़ݱճ਺ͷଟ͍ϝιου౳Λܭࢉ • ϝιου໊ͷ෮ݩ΋͜ͷλΠϛϯά Ͱߦ͏ • αϯϓϧऩू࣌͸ϙΠϯλ͚ͩΛ อ͍࣋ͯ͠Δ

Slide 25

Slide 25 text

Pf2ͷ࢓૊Έͷུ֓ αϯϓϧͷऩू ҰఆपظͰϓϩάϥϜͷ࣮ߦঢ়گΛऔಘ ूܭ ؔ਺໊ͷ෮ݩͳͲ ϏδϡΞϥΠζ Call tree΍ fl amegraphͳͲͷ෼͔Γ΍͍͢දݱ΁ • طଘͷϏδϡΞϥΠβ͕ղऍͰ͖Δ ܗࣜΛग़ྗ

Slide 26

Slide 26 text

Pf2ͷಠࣗػೳ & Pf2͕ղܾ͢Δ՝୊

Slide 27

Slide 27 text

Thread୯ҐͰͷߴ౓ͳϓϩϑΝΠϦϯά • pthread ୯ҐͰͷγάφϧઃఆ & Ruby 3.3 Ͱ௥Ճͨ͠ rb_pro fi le_thread_frames() Λར༻ • ؔ৺ͷ͋ΔεϨουΛ໌ࣔతʹࢦఆ͢Δ͜ͱ΋Մೳʹͳͬͨ 0ms 10ms 20ms 30ms Ruby Thread 1 Ruby Thread 2 SIGPROF SIGPROF Using CPU Using CPU Using CPU γάφϧϋϯυϥ rb_pro fi le_thread_frames() Λ࢖͍ελοΫΛऔಘ γάφϧϋϯυϥ

Slide 28

Slide 28 text

C (Native) ίʔυͷϓϩϑΝΠϦϯά • RubyͰ͸CͰ࣮૷͞Εͨػೳ͕ͨ͘͞Μ͋Δ • C֦ுɺRuby಺෦ͷॲཧ • RubyͷϓϩϑΝΠϦϯάػೳ rb_pro fi le_frames() Ͱ͸͜ΕΛ؍࡯Ͱ͖ͳ͍ • libbacktrace Λར༻͠ɺ࣮ߦதͷΞυϨεʢPCʣΛอଘ͢Δ͜ͱͰରԠ 0ms 10ms 20ms 30ms Ruby Thread 1 SIGPROF Using CPU Using CPU γάφϧϋϯυϥ rb_pro fi le_thread_frames() + PCͷอଘ

Slide 29

Slide 29 text

C֦ுͷϓϩϑΝΠϦϯά mysql2 gem ͷྫ read_query_result ΫΤϦͷड৴΍ύʔεʹ໰୊ ppoll ΫΤϦͷ࣮ߦ = αʔόʔଆʹ໰୊ do_send_query ΫΤϦͷૹ৴ = ωοτϫʔΫʹ໰୊

Slide 30

Slide 30 text

Ӆ͞ΕͨRubyϝιουͷൃݟ rb_hash_aref = Hash#[] CRuby ͷ࠷దԽͷ౎߹ rb_pro fi le_frames() ʹ͸ొ৔ ͠ͳ͍͕ɺC ϨϕϧͰ͸ݟ͑Δ

Slide 31

Slide 31 text

ʮݟ͑ͳ͍ʯCίʔυͷՄࢹԽ a.k.a. Native Stack Consolidation Integer#times block in Kernel#foo block (2 levels) in main() ruby_run_node() rb_ec_exec_node() rb_vm_exec() vm_exec_core() rb_yield() rb_foo() vm_call_cfunc_with_cfra main() ruby_run_node() rb_ec_exec_node() rb_vm_exec() Integer#times block in Kernel#my_cfunc vm_callc_cfunc_with_cframe() vm_exec_core() rb_yield() Kernel#foo block (2 levels) in Ruby/CͰผʑʹऩूͨ͠ ελοΫΛ "Ϛʔδ" ͢Δ ෦෼ʹ՝୊͕͋Δ

Slide 32

Slide 32 text

ʮݟ͑ͳ͍ʯCίʔυͷՄࢹԽ Integer#times block in Kernel#my_cfunc block (2 levels) in Kernel#foo block (2 levels) in main() ruby_run_node() rb_ec_exec_node() rb_vm_exec() vm_exec_core() rb_yield() rb_foo() main() ruby_run_node() rb_ec_exec_node() rb_vm_exec() ωΠςΟϒίʔυͷ main() ͔ΒߏஙΛ։࢝ rb_vm_exec() Λൃݟͨ͠ Β Ruby ελοΫʹ͏ͭΔ

Slide 33

Slide 33 text

ʮݟ͑ͳ͍ʯCίʔυͷՄࢹԽ Integer#times block in Kernel#my_cfunc block (2 levels) in Kernel#foo block (2 levels) in main() ruby_run_node() rb_ec_exec_node() rb_vm_exec() vm_exec_core() rb_yield() rb_foo() main() ruby_run_node() rb_ec_exec_node() rb_vm_exec() Integer#times block in Kernel#my_cfunc cfunc Λൃݟͨ͠Β C ͷε λοΫʹ໭Δ

Slide 34

Slide 34 text

ʮݟ͑ͳ͍ʯCίʔυͷՄࢹԽ Integer#times block in Kernel#my_cfunc block (2 levels) in Kernel#foo block (2 levels) in main() ... ... vm_callc_cfunc_with_cframe() my_cfunc() vm_exec_core() ... 0x7cabca (non-cfunc) (non-cfunc) 0x7cabca 0x7c0009 0x7c0010 #[repr(C)] pub struct rb_callable_method_entry_struct { pub flags: VALUE, pub def: *mut rb_method_definition_struct, // ... } #[repr(C)] pub struct rb_method_definition_struct { pub type_: c_int, _padding: [c_char; 4], pub cfunc: rb_method_cfunc_struct, } #[repr(C)] pub struct rb_method_cfunc_struct { pub func: *mut c_void, } ͜ͷ࢓૊ΈͷͨΊʹଟ਺ͷ struct Λ CRuby ͔Βίϐʔ͍ͯ͠Δ... rb_pro fi le_frames() ͷฦΓ஋͔ΒͨͲΕΔ cfunc ͷϙΠϯλͱҰக͢ΔΞυϨεΛϚονϯά

Slide 35

Slide 35 text

ʮݟ͑ͳ͍ʯCίʔυͷՄࢹԽ Integer#times block in Kernel#my_cfunc block (2 levels) in Kernel#foo block (2 levels) in main() ruby_run_node() rb_ec_exec_node() rb_vm_exec() vm_exec_core() rb_yield() rb_foo() main() ruby_run_node() rb_ec_exec_node() rb_vm_exec() Integer#times block in Kernel#my_cfunc vm_callc_cfunc_with_cframe() vm_exec_core() rb_yield() Kernel#foo block (2 levels) in શͯফඅͨ͠Β׬ྃ

Slide 36

Slide 36 text

ߴ౓ͳεέδϡʔϦϯά • εέδϡʔϦϯά = αϯϓϦϯάपظͷௐ੔ • Stackprof ͸ CPU time ʹରԠ͍ͯ͠Δ • ϓϩηε͕Ұఆͷ CPU ࣌ؒΛফඅͨ͠ΒαϯϓϦϯάΛ૸ΒͤΔ࢓૊Έ • ͔͠͠ɺεϨουؒͰॲཧʹภΓ͕͋Δ࣌ɺ݁Ռ͕͓͔͘͠ͳΔ • Linux ݶఆͰ͸͋Δ͕ɺtimer_create(2) ͷ CLOCK_THREAD_CPUTIME_ID ΦϓγϣϯΛ࢖͏͜ͱͰɺεϨου୯ҐͷܭଌΛ࣮ݱ͍ͯ͠Δ

Slide 37

Slide 37 text

ߴ౓ͳεέδϡʔϦϯά job() 0ms 10ms 20ms 30ms job() job() • σϑΥϧτͷपظ͸ 9ms ͱͨ͠ • Lockstep sampling (पظੑͷ͋Δ࣮ߦΛݟಀͯ͠͠·͏໰୊) ରࡦ ݟಀ͢ ݟಀ͢ ݟಀ͢

Slide 38

Slide 38 text

͓·͚: RustʹΑΔ࣮૷ͷײ૝ unsafe { • Pf2ͷC֦ு෦෼͸΄ͱΜͲRustͰ࣮૷ͨ͠ • αϯϓϧͷετϨʔδ౳Λ࣮૷͢Δʹ͋ͨͬͯ͸ྑ͔ͬͨ • Ruby C API΍libcΛݺͼग़͢෦෼Ͱ͸΄΅ C ͷݟͨ໨ (unsafe) • RustͰgemΛͭ͘ΔΤίγεςϜ͸·ͩ·ͩൃల్্ • CRuby͕ఏڙ͢ΔϚΫϩ (INT2FIX౳) ͸࢖͑ͳ͔ͬͨΓ • ruby masterͰϏϧυͰ͖ͳ͔ͬͨΓ }

Slide 39

Slide 39 text

Pf2ࣗମͷධՁ

Slide 40

Slide 40 text

ϓϩϑΝΠϥͷΦʔόʔϔουͷධՁ ࣮ߦ࣌ؒ • optcarrot (ϑΝϛίϯΤϛϡ Ϩʔλ) ͰϕϯνϚʔΫ • CPU-bound ͸ CPU ϓϩϑ ΝΠϥʹͱͬͯݫ͍͠৚݅ • Φʔόʔϔου͸ 1-2% Ͱ ͋Δ͜ͱ͕ࣔ͞Εͨ

Slide 41

Slide 41 text

ϓϩϑΝΠϥͷΦʔόʔϔουͷධՁ ফඅϝϞϦ • ऩूͨ͠αϯϓϧΛϝϞϦʹอଘ͢Δ౎߹্ɺϝϞϦফඅ͸૿େ͢Δ • 3.01ඵͷ optcarrot ࣮ߦͰͷϝϞϦফඅ (time -v ʹΑΔ maximum RSS) • Pf2ແޮ ... 58.9 MB • Pf2༗ޮ ... 69.3 MB • ελοΫͷେ͖͞ͱ࣌ؒʹରͯ͠ઢܗʹ৳ͼΔ • RailsΞϓϦέʔγϣϯͰ͸ΑΓݦஶʹͳΔ

Slide 42

Slide 42 text

ϝϞϦফඅͷվળ΁ • αϯϓϧ1ͭ͋ͨΓ14KBͷ͸ͣ • 111 samples/ඵ = 1.5 MB/ඵ • ·ͨɺframesΛ࣋ͭ͜ͱͰCRubyͷ ϑϨʔϜ (Callable Method Entry) ͕ GC͞Εͳ͘ͳΓɺϝϞϦফඅ͕૿େ • ਖ਼֬ͳௐࠪʹ͸ϓϩϑΝΠϥͷ ϓϩϑΝΠϥ͕ඞཁ……ʂ // 14038 bytes (14 KB) pub struct Sample { pub ruby_thread: VALUE, // 8 bytes pub timestamp: Instant, // 16 bytes pub line_count: i32, // 4 bytes // frames = rb_profile_frames() pub frames: [VALUE; 500], // 4000 bytes pub linenos: [i32; 500], // 2000 bytes // 8008 bytes pub c_backtrace_pcs: [usize; 1001], }

Slide 43

Slide 43 text

ಘΒΕͨελοΫͷਖ਼͠͞ͷධՁ • ϓϩϑΝΠϥ͕ग़ྗͨ͠ελοΫ͕ਅʹਖ਼͍͔͠Λ֬ೝ͢Δ͜ͱ͸ ඇৗʹ೉͍͠ • ͍͔ͭ͘ͷϝιου΍ϑϨʔϜΛඈ͹ͯ͠͠·͍ͬͯͯ΋ؾͮ͘͜ͱ͕ࠔ೉ • ݕূ͢ΔϑϨʔϜϫʔΫΛ࣮૷தʢະ׬੒ʣ • ͱ͸͍ͬͯ΋ɺperf ͷ݁Ռ౳ͱಥ͖߹ΘͤΔҎ֎ͷํ๏͸ ࢥ͍͍͍ͭͯͳ͍

Slide 44

Slide 44 text

Pf2ͱRubyϓϩϑΝΠϦϯάͷະདྷ

Slide 45

Slide 45 text

Pf2ͷ௚ۙͷະདྷ • ϝϞϦΛফඅ͗͢͠Δ໰୊ͷվળ • "࣮༻Խ" ʹ޲͚ͨ࡞ۀ & ࣮੷ͮ͘Γ • RailsΞϓϦέʔγϣϯʹ૊ΈࠐΉΨΠυͷࣥච • ػೳͷ௥Ճ

Slide 46

Slide 46 text

ॲཧܥͱϓϩϑΝΠϥͷؔ܎ͷมԽ • C API ΍ॲཧܥͷ಺෦࣮૷Λ΋؍࡯ ͠Α͏ͱࢥ͏ͱɺॲཧܥͷ಺෦Ҏ֎ ʹஔ͖৔ॴ͕ͳ͍ • M:N ͕ਐΉͱɺ1 Thread = 1 pthread ͷԾఆ͕յΕɺݱࡏͷख๏͕ద༻͠ ͮΒ͘ͳΔ • → CRuby ʹػೳΛ௥Ճ͍ͯ͘͠ํ๏ Λݕ౼ current Pf2

Slide 47

Slide 47 text

ϓϩϑΝΠϦϯάࣗମͷཱͪҐஔͷมԽ • ʮύϑΥʔϚϯεͷ໰୊Λमਖ਼͢Δʯ࣌ͷϓϩϑΝΠϦϯά͔Β ʮύϑΥʔϚϯεͷ໰୊Λൃݟ͢ΔʯϓϩϑΝΠϦϯά΁ • ໰୊͕ݟ͔͔ͭͬͯΒϓϩϑΝΠϥΛಋೖ͢Δͷ͸গ͠େม • Rails౳ͷdaemonͱͯ͠ಈ࡞͢ΔΞϓϦέʔγϣϯͰ͸ɺ ৗʹϓϩϑΝΠϧ͕࠾औ͞Ε͍ͯΔͷ͕౰ͨΓલʹͳͬͯ΄͍͠

Slide 48

Slide 48 text

·ͱΊ • ৽͍͠ϓϩϑΝΠϥ "Pf2" Λ։ൃ͠·ͨ͠ • Ruby ݻ༗ͷػೳʹΑ͘ରԠͨ͠ϓϩϑΝΠϥͱͯ͠ ࠓޙ΋ਐԽ͍ͤͨ͞ • Ruby ϓϩϑΝΠϦϯάͷ؀ڥશମΛྑ͍͖͍ͯͨ͘͠

Slide 49

Slide 49 text

ँࣙ • Ұൠࣾஂ๏ਓRubyΞιγΤʔγϣϯ • ϝϯλʔͷࠃ෼ʢk0kubunʣ͞Μ • ΞυόΠεΛͩͬͨ͘͞࡫ా͞Μɺԕ౻͞Μ