-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
maglev: Allocate permutations slice ahead of time #14622
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice! Some comments.
4031d65
to
67f4e7c
Compare
test-me-please |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Two nits, otherwise LGTM.
2f91c70
to
be5555a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚀
test-me-please |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few nits.
CI has passed. Pushing fixups to nits, which don't require a re-run of CI. |
af12caa
to
1159b37
Compare
989c1bf
to
b14d077
Compare
b14d077
to
9201cdd
Compare
test-me-please |
Previously, the Maglev permutations slice is allocated inside `getPermutation()`, which means every time `maglev.GetLookupTable()` is called, the slice will be recreated. That means it would recreated on every Service creation or update. This commit allocates the slice ahead of time when the Maglev subsystem is initialized (`maglev.Init()`). This gives a rough improvement in time of around 15%. The slice is allocated based on a heuristic computation, involving the M size. Nodes running with less than 8GB of RAM do not apply and Cilium will not be preallocate the slice ahead of time. For nodes with more than the aforementioned threshold, the formula for the heuristic is: (M / 100) * 100 This is derived from the maximum backends property from Maglev where |backends| * 100 < M. This gives the following memory pressure profile based on M (left-hand side): 251: 0.004806594848632812 MB 509: 0.019766311645507812 MB 1021: 0.07953193664550783 MB 2039: 0.3171936798095703 MB 4093: 1.2781256866455077 MB 8191: 5.118750076293945 MB 16381: 20.472500686645507 MB 32749: 81.82502754211426 MB 65521: 327.5300171661377 MB 131071: 1310.700000076294 MB If the user has more backends than the preallocated size, we will adjust the allocation to be |backends| * M. This is because we want to ensure that the Maglev subsystem isn't thrashing trying to reallocate the slice on each Service create or update. Benchmark timings: Before ``` $ go test -v ./pkg/maglev -check.v -check.b -check.btime 5s -check.bmem === RUN Test PASS: maglev_test.go:91: MaglevTestSuite.BenchmarkGetMaglevTable 50 341255883 ns/op1049633800 B/op 12 allocs/op OK: 1 passed --- PASS: Test (17.42s) PASS ok github.com/cilium/cilium/pkg/maglev 17.475s ``` After ``` $ go test -v ./pkg/maglev -check.v -check.b -check.btime 5s -check.bmem === RUN Test PASS: maglev_test.go:91: MaglevTestSuite.BenchmarkGetMaglevTable 50 282792516 ns/op 1057899 B/op 11 allocs/op OK: 1 passed --- PASS: Test (17.89s) PASS ok github.com/cilium/cilium/pkg/maglev 17.943s ``` Suggested-by: Martynas Pumputis <m@lambda.lt> Signed-off-by: Chris Tarazi <chris@isovalent.com>
9201cdd
to
b15cd54
Compare
CI passed on the last run. Pushed a change that only updated the comments so no actual code was changed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚀
Previously, the Maglev permutations slice is allocated inside
getPermutation()
, which means every timemaglev.GetLookupTable()
iscalled, the slice will be recreated. That means it would recreated on
every Service creation or update.
This commit allocates the slice ahead of time when the Maglev subsystem
is initialized (
maglev.Init()
). This gives a rough improvement in timeof around 15%.
The slice is allocated based on a heuristic computation, involving the M
size. Nodes running with less than 8GB of RAM do not apply and Cilium
will not be preallocate the slice ahead of time. For nodes with more
than the aforementioned threshold, the formula for the heuristic is:
This is derived from the maximum backends property from Maglev where
|backends| * 100 < M. This gives the following memory pressure profile
based on M (left-hand side):
If the user has more backends than the preallocated size, we will adjust
the allocation to be |backends| * M. This is because we want to ensure
that the Maglev subsystem isn't thrashing trying to reallocate the slice
on each Service create or update.
Benchmark timings:
Before
After
Suggested-by: Martynas Pumputis m@lambda.lt
FlameGraphs:
Related: #14397