Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Golang Escape Analysis

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
Avatar for koya fukushi koya fukushi
August 31, 2017
440

Golang Escape Analysis

Avatar for koya fukushi

koya fukushi

August 31, 2017
Tweet

Transcript

  1. 2017/8/30 Go Escape Analysis http://go-talks.appspot.com/github.com/Kooooya/slides/2017/0829_with_navitime/escape_analysis_0.slide#1 2/26 エスケープ解析とは? サブルーチンにおいて変数やオブジェクトが割り当てられるとき、変数へのポインタ が、別の実行スレッドや呼び出し元のルーチンに「エスケープ」してしまうことがあ る。

    オブジェクトがサブルーチン内で割り当てられ、オブジェクトへのポインタがエスケー プしなければ、そのオブジェクトはヒープの代わりにスタックに割り当てる候補にな る。 https://ja.wikipedia.org/wiki/ エスケープ解析 (https://ja.wikipedia.org/wiki/%E3%82%A8%E3%82%B9%E3%82%B1%E3%83%BC%E3%83%97%E8%A7%A3%E6%9E%90)
  2. 2017/8/30 Go Escape Analysis http://go-talks.appspot.com/github.com/Kooooya/slides/2017/0829_with_navitime/escape_analysis_0.slide#1 4/26 やってみる -m エスケープ解析を出力 -l

    関数のインライン化を無効(今回は例をわかりやすくするために) $ go run -gcflags '-m -l' escape_analysis.go $ 最初の例は何も出力されない(エスケープが無い)
  3. 2017/8/30 Go Escape Analysis http://go-talks.appspot.com/github.com/Kooooya/slides/2017/0829_with_navitime/escape_analysis_0.slide#1 6/26 やってみる $ go run

    -gcflags '-m -l' escape_analysis1.go # command-line-arguments ./escape_analysis1.go:11: leaking param: z to result ~r1 level=0 ./escape_analysis1.go:7: main &x does not escape go は関数の引数は値渡しなので、identity にz のコピーが渡される けどz はidentity で参照されていないのでエスケープされなかった
  4. 2017/8/30 Go Escape Analysis http://go-talks.appspot.com/github.com/Kooooya/slides/2017/0829_with_navitime/escape_analysis_0.slide#1 8/26 やってみる $ go run

    -gcflags '-m -l' escape_analysis2.go # command-line-arguments ./escape_analysis2.go:11: &z escapes to heap ./escape_analysis2.go:10: moved to heap: z ref はz の参照を返すから、z はref のスタックフレームに入らない main にも見えるようにヒープに格納される
  5. 2017/8/30 Go Escape Analysis http://go-talks.appspot.com/github.com/Kooooya/slides/2017/0829_with_navitime/escape_analysis_0.slide#1 10/26 やってみる $ go run

    -gcflags '-m -l' escape_analysis3.go # command-line-arguments ./escape_analysis3.go:13: &y escapes to heap ./escape_analysis3.go:12: moved to heap: y 構造体のフィールドであってもエスケープされる
  6. 2017/8/30 Go Escape Analysis http://go-talks.appspot.com/github.com/Kooooya/slides/2017/0829_with_navitime/escape_analysis_0.slide#1 12/26 やってみる $ go run

    -gcflags '-m -l' escape_analysis4.go # command-line-arguments ./escape_analysis4.go:12: leaking param: y to result z level=0 ./escape_analysis4.go:9: main &i does not escape main のスタックフレーム内の参照だから、refStruct のz.y の値は知っている 参照が循環される。エスケープされない
  7. 2017/8/30 Go Escape Analysis http://go-talks.appspot.com/github.com/Kooooya/slides/2017/0829_with_navitime/escape_analysis_0.slide#1 14/26 やってみる $ go run

    -gcflags '-m -l' escape_analysis5.go # command-line-arguments ./escape_analysis5.go:13: leaking param: y ./escape_analysis5.go:13: ref z does not escape ./escape_analysis5.go:10: &i escapes to heap ./escape_analysis5.go:9: moved to heap: i ./escape_analysis5.go:10: main &x does not escape 入力された構造体に代入している 解析での入力は出力の値に対してのみ許可されている
  8. 2017/8/30 Go Escape Analysis http://go-talks.appspot.com/github.com/Kooooya/slides/2017/0829_with_navitime/escape_analysis_0.slide#1 15/26 やってみる package main type

    S struct { M *int } func main() { ref() } func ref() (z S) { var i = [5]int{1, 2, 3, 4, 5} z.M = &i[0] return z }
  9. 2017/8/30 Go Escape Analysis http://go-talks.appspot.com/github.com/Kooooya/slides/2017/0829_with_navitime/escape_analysis_0.slide#1 16/26 やってみる $ go run

    -gcflags '-m -l' escape_analysis6.go # command-line-arguments ./escape_analysis6.go:13: &i[0] escapes to heap ./escape_analysis6.go:12: moved to heap: i 配列は一つの要素でもエスケープされてしまうと、全体もエスケープされる 一つもエスケープされないと、スタックフレームに乗る
  10. 2017/8/30 Go Escape Analysis http://go-talks.appspot.com/github.com/Kooooya/slides/2017/0829_with_navitime/escape_analysis_0.slide#1 17/26 やってみる package main type

    S struct { M *int } func main() { ref() } func ref() (z S) { var i = [5]int{1, 2, 3, 4, 5} _i := i[0] z.M = &_i return z }
  11. 2017/8/30 Go Escape Analysis http://go-talks.appspot.com/github.com/Kooooya/slides/2017/0829_with_navitime/escape_analysis_0.slide#1 18/26 やってみる $ go run

    -gcflags '-m -l' escape_analysis7.go # command-line-arguments ./escape_analysis7.go:14: &_i escapes to heap ./escape_analysis7.go:13: moved to heap: _i _i だけエスケープされた。 slice 全体じゃないので効率的
  12. 2017/8/30 Go Escape Analysis http://go-talks.appspot.com/github.com/Kooooya/slides/2017/0829_with_navitime/escape_analysis_0.slide#1 20/26 やってみる $ go test

    -gcflags="-m -l" -bench=. escape_analysis8.go # command-line-arguments ./escape_analysis8.go:9: &v escapes to heap ./escape_analysis8.go:6: moved to heap: v ./escape_analysis8.go:8: main make(map[int]*S) does not escape map のvalue にセットされたポインターは常にエスケープされる
  13. 2017/8/30 Go Escape Analysis http://go-talks.appspot.com/github.com/Kooooya/slides/2017/0829_with_navitime/escape_analysis_0.slide#1 22/26 やってみる $ go test

    -gcflags="-m -l" -bench=. escape_analysis8.go # command-line-arguments ./escape_analysis9.go:9: &v escapes to heap ./escape_analysis9.go:6: moved to heap: v ./escape_analysis9.go:8: main []*S literal does not escape slice のvalue にセットされたポインターは常にエスケープされる
  14. 2017/8/30 Go Escape Analysis http://go-talks.appspot.com/github.com/Kooooya/slides/2017/0829_with_navitime/escape_analysis_0.slide#1 24/26 Links Golang Escape Analisis

    blog.rocana.com/golang-escape-analysis (http://blog.rocana.com/golang-escape-analysis) Go Escape Analysis Flaws docs.google.com/document/d/1CxgUBPlx9iJzkz9JWkb6tIpTe5q32QDmz8l0BouG0Cw/preview (https://docs.google.com/document/d/1CxgUBPlx9iJzkz9JWkb6tIpTe5q32QDmz8l0BouG0Cw/preview)