-
Notifications
You must be signed in to change notification settings - Fork 191
Merge shuffle score pods logic #1552
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
Merge shuffle score pods logic #1552
Conversation
✅ Deploy Preview for gateway-api-inference-extension ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
Hi @learner0810. Thanks for your PR. I'm waiting for a kubernetes-sigs member to verify that this patch is reasonable to test. If it is, they should reply with Once the patch is verified, the new status will be reflected by the I understand the commands that are listed here. Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. |
5ade12d to
6ac1fe4
Compare
|
/ok-to-test |
|
/lgtm |
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: kfswain, learner0810 The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
| func shuffleScoredPods(scoredPods []*types.ScoredPod) { | ||
| // Rand package is not safe for concurrent use, so we create a new instance. | ||
| // Source: https://pkg.go.dev/math/rand/v2#pkg-overview | ||
| randomGenerator := rand.New(rand.NewPCG(uint64(time.Now().UnixNano()), 0)) |
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.
have you compared using sync.Pool vs creating a new random source every time?
I don't expect much latency difference but a sync.Pool would reduce GC pressure as these are created and collected per request.
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.
func shuffleScoredPods(scoredPods []*types.ScoredPod) {
// Rand package is not safe for concurrent use, so we create a new instance.
// Source: https://pkg.go.dev/math/rand/v2#pkg-overview
randomGenerator := rand.New(rand.NewPCG(uint64(time.Now().UnixNano()), 0))
// Shuffle in-place
randomGenerator.Shuffle(len(scoredPods), func(i, j int) {
scoredPods[i], scoredPods[j] = scoredPods[j], scoredPods[i]
})
}
var randPool = sync.Pool{
New: func() interface{} {
return rand.New(rand.NewPCG(uint64(time.Now().UnixNano()), 0))
},
}
func shuffleScoredPodsWithPool(scoredPods []*types.ScoredPod) {
randomGenerator := randPool.Get().(*rand.Rand)
defer randPool.Put(randomGenerator)
// Shuffle in-place
randomGenerator.Shuffle(len(scoredPods), func(i, j int) {
scoredPods[i], scoredPods[j] = scoredPods[j], scoredPods[i]
})
}func createTestScoredPods(count int) []*types.ScoredPod {
pods := make([]*types.ScoredPod, count)
for i := 0; i < count; i++ {
pods[i] = &types.ScoredPod{
Pod: &types.PodMetrics{
Pod: &backend.Pod{
NamespacedName: k8stypes.NamespacedName{
Name: "pod-" + strconv.Itoa(i),
Namespace: "namespace-" + strconv.Itoa(i),
},
},
},
Score: float64(i),
}
}
return pods
}
func BenchmarkShuffleScoredPods(b *testing.B) {
testPods := createTestScoredPods(100)
b.ResetTimer()
for i := 0; i < b.N; i++ {
podsCopy := make([]*types.ScoredPod, len(testPods))
copy(podsCopy, testPods)
shuffleScoredPods(podsCopy)
}
}
func BenchmarkShuffleScoredPodsWithPool(b *testing.B) {
testPods := createTestScoredPods(100)
b.ResetTimer()
for i := 0; i < b.N; i++ {
podsCopy := make([]*types.ScoredPod, len(testPods))
copy(podsCopy, testPods)
shuffleScoredPodsWithPool(podsCopy)
}
}
func BenchmarkShuffleScoredPods_Small(b *testing.B) {
testPods := createTestScoredPods(10)
b.ResetTimer()
for i := 0; i < b.N; i++ {
podsCopy := make([]*types.ScoredPod, len(testPods))
copy(podsCopy, testPods)
shuffleScoredPods(podsCopy)
}
}
func BenchmarkShuffleScoredPodsWithPool_Small(b *testing.B) {
testPods := createTestScoredPods(10)
b.ResetTimer()
for i := 0; i < b.N; i++ {
podsCopy := make([]*types.ScoredPod, len(testPods))
copy(podsCopy, testPods)
shuffleScoredPodsWithPool(podsCopy)
}
}
func BenchmarkShuffleScoredPods_Large(b *testing.B) {
testPods := createTestScoredPods(1000)
b.ResetTimer()
for i := 0; i < b.N; i++ {
podsCopy := make([]*types.ScoredPod, len(testPods))
copy(podsCopy, testPods)
shuffleScoredPods(podsCopy)
}
}
func BenchmarkShuffleScoredPodsWithPool_Large(b *testing.B) {
testPods := createTestScoredPods(1000)
b.ResetTimer()
for i := 0; i < b.N; i++ {
podsCopy := make([]*types.ScoredPod, len(testPods))
copy(podsCopy, testPods)
shuffleScoredPodsWithPool(podsCopy)
}
}I have tested it locally and the test result is as follows. If there is any problem, please point it out. If the test results are accurate, do you think it needs to be optimized?
host@hostdeMacBook-Pro picker % go test -bench=. -benchmem
goos: darwin
goarch: amd64
pkg: sigs.k8s.io/gateway-api-inference-extension/pkg/epp/scheduling/framework/plugins/picker
cpu: Intel(R) Core(TM) i5-1038NG7 CPU @ 2.00GHz
BenchmarkShuffleScoredPods-8 911576 1245 ns/op 912 B/op 2 allocs/op
BenchmarkShuffleScoredPodsWithPool-8 1000000 1130 ns/op 896 B/op 1 allocs/op
BenchmarkShuffleScoredPods_Small-8 4351080 247.4 ns/op 96 B/op 2 allocs/op
BenchmarkShuffleScoredPodsWithPool_Small-8 7934428 139.8 ns/op 80 B/op 1 allocs/op
BenchmarkShuffleScoredPods_Large-8 115184 10405 ns/op 8208 B/op 2 allocs/op
BenchmarkShuffleScoredPodsWithPool_Large-8 115098 10628 ns/op 8195 B/op 1 allocs/op
PASS
ok sigs.k8s.io/gateway-api-inference-extension/pkg/epp/scheduling/framework/plugins/picker 7.652s
| "time" | ||
|
|
||
| "sigs.k8s.io/controller-runtime/pkg/log" | ||
|
|
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.
please keep import groups separated and not combine controller-runtime (3rd-party/ external) with gateway-api-inference-extension (local/internal)
| "time" | ||
|
|
||
| "sigs.k8s.io/controller-runtime/pkg/log" | ||
|
|
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.
ditto
What type of PR is this?
/kind cleanup
What this PR does / why we need it:
Merge shuffle score pods logic
Which issue(s) this PR fixes:
Fixes #
Does this PR introduce a user-facing change?: