Feb 23, 2020

[Go] runtime bounds check elimination

Reference:
https://go101.org/article/bounds-check-elimination.html
https://groups.google.com/forum/?utm_medium=email&utm_source=footer#!msg/golang-nuts/TItWw4srDgg/HwGy7JmbBQAJ
https://github.com/golang/exp/tree/master/shiny/driver/internal/swizzle

Since Go SDK 1.7, the standard Go compiler has used a new compiler backend, which based on SSA (static single-assignment form, simply put, i.e versioning the expression).

SSA helps Go compilers effectively use optimizations like BCE (bounds check elimination) and CSE (common subexpression elimination).

Check which code line still using bound check:
$ go build -gcflags="-d=ssa/check_bce/debug=1"


Sometimes, we can make some hints to help the compiler eliminate some unnecessary bounds checks:
// example from https://go101.org/article/bounds-check-elimination.html
// example5.go
package main

func fd(is []int, bs []byte) {
 if len(is) >= 256 {
  for _, n := range bs {
   _ = is[n] // line 8: bounds check
  }
 }
}

func fd2(is []int, bs []byte) {
 if len(is) >= 256 {
  is = is[:256] // line 15: a hint
  for _, n := range bs {
   _ = is[n] // line 17: BCEed!
  }
 }
}

func fe(isa []int, isb []int) {
 if len(isa) > 0xFFF {
  for _, n := range isb {
   _ = isa[n & 0xFFF] // line 25: bounds check
  }
 }
}

func fe2(isa []int, isb []int) {
 if len(isa) > 0xFFF {
  isa = isa[:0xFFF+1] // line 32: a hint
  for _, n := range isb {
   _ = isa[n & 0xFFF] // line 34: BCEed!
  }
 }
}

func main() {}

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.