Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

goroutineはどうやって動いているのか

460 views

Published on

https://shinjukurb.connpass.com/event/91172/
の発表資料です。

Published in: Engineering
  • Be the first to comment

  • Be the first to like this

goroutineはどうやって動いているのか

  1. 1. ota42y 2018/06/26 Shinjuku.rb #62 goroutineは どうやって動いているのか
  2. 2. • ota42y • サーバサイドエンジニア • rubyとかrustとかgoとかC++とか • Twitter、github → ota42y • 技術書典4でマイクロサービス本を出した – https://ota42y.com/blog/2018/04/10/mi croservices_yorozu_book/ 自己紹介
  3. 3. goroutine
  4. 4. • go func で関数を非同期にする凄いヤツ • 簡単すぎて内部で何をやっているか謎 →内でどう動いているか調べた goroutine
  5. 5. • goroutineはプロセッサ数に応じて適切に 分散されて動く • スレッドを作りすぎないよう上手くやる • 基本はwork-stealingアルゴリズム 結論
  6. 6. goroutineは何をするか
  7. 7. • このコード goroutine開始時
  8. 8. • こんな感じになる • newprocに関数を渡してそう • newprocはnewproc1をほぼ読んでるだけ • `go` の中身はnewproc1っぽい goroutine開始時
  9. 9. newproc1
  10. 10. newproc1 (´・_・`)
  11. 11. Design doc • スケジューラのDesign docがある – https://golang.org/s/go11sched – おそらくgo 1.1? • 大きくは変わって無さそうなので適応できる
  12. 12. goroutineのスケジューラー • 登場人物は3つ – P • Processor – M • Thread – G • gorutineに渡された関数
  13. 13. goroutineのスケジューラー • 登場人物は3つ – P • Gを処理していくプロセッサ • GOMAXPROCSの数だけPがある – M • 特定のPに紐付いている – G
  14. 14. goroutineの登録 G P M G Gは発行されると キューに入る head
  15. 15. goroutineの登録 G P G M PはGを取り出してMに くっつけて実行する head
  16. 16. goroutineの登録 G P M G PはGを取り出してMに くっつけて実行する head
  17. 17. goroutineの登録 G P M G M Mが待ちになるとPは 別のMを処理する (syscallとかロックとか) head
  18. 18. goroutineの登録 P M G M G Mが待ちになるとPは 別のMを処理する (syscallとかロックとか) head
  19. 19. goroutineのスケジュール
  20. 20. goroutineのスケジュール G P M G G P M 複数Pが存在する場合 head
  21. 21. goroutineのスケジュール G P M G G P M 複数Pが存在する場合 →デッドロックが起きる 並列数を増やしても性 能を上げられない head
  22. 22. goroutineのスケジュール G P M G P M Pごとにキューを持つ GG
  23. 23. goroutineのスケジュール G P M G P M Pごとにキューを用意 →自分のキューから取る ことでデッドロック回避GG
  24. 24. goroutineのスケジュール G P M G P M P間でGの量に差が出る あるPは急がしいが 別のPは暇の場合がある 適切な負荷分散が必要
  25. 25. work-stealing
  26. 26. • 暇なworkerが、別のworkerからjobを stealする(盗む)アルゴリズム • 中央の管理者無しで良い感じにjobが分散 するらしい • 別workerへのアクセス回数が少なく 競合が発生しにくい work-stealing
  27. 27. work-stealing G P M G P M キューからGが無くなる
  28. 28. work-stealing G P M G P M キューからGが無くなる 別Pのキューにアクセス
  29. 29. work-stealing G P M G P M キューからGが無くなる 別Pのキューにアクセス 中身を半分奪う
  30. 30. work-stealing G P M G P M 普段は自キューを使う →デッドロック回避 空になったときだけ奪う →他キューへのアクセス は少ない
  31. 31. work-stealing G P M G P M キューがあふれたときに 半分globalキューに詰む globalキューは両端キュー 先にglobalキューから stealする G
  32. 32. • goroutineは関数をキューに積むだけ • スケジューラがプロセッサ数に応じて適 切に分散される • 基本はwork-stealingアルゴリズム • スレッドも良い感じに使い回す まとめ
  33. 33. • 両端キューではなく片側キューを使ってる – タブンネ – 両端キューだとより性能が良いはず • 先頭から取り出して後ろから盗む • headを触るのはその所有者のPのみ – キューの実装が循環キューなのが関係している? • メモリ消費かも(両端キューのほうが消費量多いはず) • Pを移動するさいのメモリの扱いとか – もうちょっとdeepに踏み込むのが必要そう わかんなかったこと
  34. 34. • https://golang.org/s/go11sched • https://github.com/golang/go/blob/0 a7ac93c27c9ade79fe0f66ae0bb81484 c241ae5/src/runtime/proc.go • https://rakyll.org/scheduler/ 参考資料

×