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

Golang Escape Analysis

koya fukushi
August 31, 2017
330

Golang Escape Analysis

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)