Why cgo is slow @ CapitalGo 2018

Why cgo is slow @ CapitalGo 2018

https://capitalgolang.com/program#filippo_valsorda

This talk uses cgo and its below-average performance as an excuse to look into Go internals and what makes Go different from C.

We learn about calling conventions and the code-generated cgo trampolines; about the small goroutines stacks and how C doesn't know how to grow them; about the Go scheduler and how C doesn't yield to it; and about the garbage collector and how pointers in C memory can't be tracked.

9fdab9d005b82612cadbfe699b541f83?s=128

Filippo Valsorda

June 22, 2018
Tweet

Transcript

  1. Why cgo is slow Filippo Valsorda

  2. None
  3. cgo is a FFI (Foreign Function Interface)

  4. I like FFIs. • From cgo back to Go @

    GopherCon 2016
 https://speakerdeck.com/filosottile/from-cgo-back-to-go-gophercon-2016 • rustgo: Building your own FFI @ GothamGo 2017
 https://speakerdeck.com/filosottile/calling-rust-from-go-without-cgo-at-gothamgo-2017 • Why cgo is slow @ CapitalGo 2018
 Hi!
  5. C function call Java FFI Rust FFI LuaJIT FFI Node.js

    FFI cgo 2.364 ns 9.01 ns 2.386 ns 1.81 ns (!) https://nullprogram.com/blog/2018/05/27/ 18.33 ns 75.95 ns https://github.com/dyu/ffi-overhead
  6. name old time/op new time/op delta CgoCall-4 63.1ns ± 3%

    57.1ns ± 0% -9.43%
  7. C function call Java FFI Rust FFI LuaJIT FFI Node.js

    FFI cgo 2.364 ns 9.01 ns 2.386 ns 1.81 ns (!) https://nullprogram.com/blog/2018/05/27/ 18.33 ns 68.77 ns https://github.com/dyu/ffi-overhead
  8. C function call Java FFI Rust FFI LuaJIT FFI Node.js

    FFI cgo 2.364 ns 9.01 ns 2.386 ns 1.81 ns (!) https://nullprogram.com/blog/2018/05/27/ 18.33 ns 68.77 ns (29x) https://github.com/dyu/ffi-overhead
  9. cgo: • cmd/cgo • runtime/cgo • a sprinkle of cmd/link/internal/ld

    support
  10. cgo: • cmd/cgo • runtime/cgo • a sprinkle of cmd/link/internal/ld

    support • not a compiler feature!
  11. cgo: • cmd/cgo — a code generator • runtime/cgo •

    a sprinkle of cmd/link/internal/ld support • not a compiler feature!
  12. Reason 1: calling conventions

  13. C compiler Go compiler

  14. go build -x -work

  15. None
  16. None
  17. None
  18. None
  19. src/runtime/cgocall.go

  20. None
  21. None
  22. None
  23. rewritten Go function calling convention trampoline arg unpacking real C

    function Go ASM C
  24. Learn more: • src/runtime/cgocall.go • rustgo: Building your own FFI

    @ GothamGo 2017
 https://speakerdeck.com/filosottile/calling-rust-from-go-without-cgo-at-gothamgo-2017
  25. Reason 2: small stacks

  26. Initial goroutine stack size: 2048 bytes System stack size: 1–8

    megabytes
  27. stack

  28. function frame

  29. None
  30. None
  31. None
  32. None
  33. None
  34. Function preamble

  35. C doesn't call morestack C code needs to run on

    a system stack cgocall / asmcgocall
  36. Learn more: • src/runtime/stack.go • src/runtime/cgocall.go • How stacks are

    handled in Go by Daniel Morsing
 https://blog.cloudflare.com/how-stacks-are-handled-in-go/
  37. Reason 3: the scheduler

  38. From https://morsmachine.dk/go-scheduler

  39. From https://morsmachine.dk/go-scheduler

  40. The Go scheduler is collaborative. It can't preempt running code.

    (ProTip: for {} is never what you want. Use select {}.)
  41. None
  42. From https://morsmachine.dk/go-scheduler

  43. Learn more: • src/runtime/proc.go → reentersyscall • The Go scheduler

    by Daniel Morsing
 https://morsmachine.dk/go-scheduler • Performance without the event loop by Dave Cheney
 https://dave.cheney.net/2015/08/08/performance-without-the-event-loop
  44. Reason 4: the garbage collector

  45. Go memory C memory []byte

  46. Go memory C memory GC []byte

  47. Go memory C memory GC []byte

  48. Go memory C memory GC []byte *uint8_t C.some_func()

  49. The cgo rules You may pass a Go pointer …

    if it doesn’t point to other pointers … and C can’t keep a reference to it
  50. The GC must see all the Go pointers.

  51. panic: runtime error: cgo argument has Go pointer to Go

    pointer GODEBUG=cgocheck=2
  52. Learn more: • From cgo back to Go @ GopherCon

    2016
 https://speakerdeck.com/filosottile/from-cgo-back-to-go-gophercon-2016
  53. Thank you! filippo@golang.org @FiloSottile Olga Shalakhina artwork under CC 3.0

    license based on Renee French under Creative Commons 3.0 Attributions.