Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reduce GC in DSL #424

Merged
merged 10 commits into from
Feb 22, 2021
Merged

Reduce GC in DSL #424

merged 10 commits into from
Feb 22, 2021

Conversation

johnkerl
Copy link
Owner

@johnkerl johnkerl commented Feb 22, 2021

Overview

Avoid some data-copies -- having lots of little mallocs (even with bounded heap) doesn't work as well in Go as in C.

Idea is for z = x + y, instead of func MlrvalPlus(input1, input2 *Mlrval) Mlrval, do func MlrvalPlus(output, input1, input2 *Mlrval) where the output space is pre-allocated for each relevant CST node.

Details

  • With GC enabled: there is lots of GC
  • With GC off: still lots of duffcopy and madvise taking CPU cycles
  • From benchmark u/mand.mlr: issue is allocation created by expressions
    • Things like type BinaryFunc func(input1 *Mlrval, input2 *Mlrval) (output Mlrval)
    • z = 2 + x + 4 + y * 3 results in AST, mapped to a CST, with a malloc on the output of every unary/binary/ternary function
    • Idea: replace with type BinaryFunc func(output* Mlrval, input1 *Mlrval, input2 *Mlrval): no allocation at all.
      • Breaks the Fibonacci test since the binary-operator node is no longer re-entrant
    • Idea: replace with type BinaryFunc func(input1 *Mlrval, input2 *Mlrval) (output *Mlrval): better.
      • Makes possible zero-copy eval of literal nodes, etc.
for i in 100 200 300 400 500 600 700 800 900 1000 ; do
  for j in 1 2 3 4 5 ; do
    echo $i;
    justtime GOGC=$i mlr -n put -q -f u/mand.mlr > /dev/null
  done
done
 100 23.754
 100 23.883
 100 24.021
 100 24.022
 100 24.305
 200 20.864
 200 20.211
 200 19.980
 200 20.251
 200 20.691
 300 19.140
 300 18.610
 300 18.793
 300 19.111
 300 19.027
 400 18.067
 400 18.274
 400 18.344
 400 18.378
 400 18.250
 500 17.791
 500 17.644
 500 17.814
 500 18.064
 500 18.403
 600 17.878
 600 17.892
 600 18.034
 600 18.125
 600 18.008
 700 18.153
 700 18.286
 700 17.342
 700 21.136
 700 20.729
 800 19.585
 800 19.116
 800 17.170
 800 18.549
 800 18.236
 900 16.950
 900 17.883
 900 17.532
 900 17.551
 900 17.804
1000 20.076
1000 20.745
1000 19.657
1000 18.733
1000 18.560

Sweet spot around 500. Note https://golang.org/pkg/runtime/debug/#SetGCPercent.

How to control garbage collection

# Note 100 is the default
# Raise the bar for GC threshold:
GOGC=200  GODEBUG=gctrace=1 mlr -n put -q -f u/mand.mlr 1> /dev/null

# Raise the bar higher for GC threshold:
GOGC=1000 GODEBUG=gctrace=1 mlr -n put -q -f u/mand.mlr 1> /dev/null

# Turn off GC entirely and see where time is spent:
GOGC=off  GODEBUG=gctrace=1 mlr -n put -q -f u/mand.mlr 1> /dev/null

@johnkerl johnkerl merged commit a467f91 into master Feb 22, 2021
@johnkerl johnkerl deleted the reduce-gc-in-dsl branch February 22, 2021 06:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant