perf(scheduler): stop deep-copying whole Pods into the usage snapshot - #2978
perf(scheduler): stop deep-copying whole Pods into the usage snapshot#2978togettoyou wants to merge 1 commit into
Conversation
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: togettoyou The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Team Run ID: 📒 Files selected for processing (6)
Included review availability: Your plan provides up to 8 included reviews per hour; 7 remain after this review. 📝 WalkthroughWalkthrough
ChangesPod snapshot semantics
Estimated code review effort: 3 (Moderate) | ~20 minutes Merge Risk: ⚪ Minimal · up to This change reduces scheduler allocation overhead by sharing read-only Pod objects while preserving independent device-accounting snapshots. The updated retrieval and copy semantics are covered, with no concrete current-head merge-blocking risk identified. Suggested labels: Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Signed-off-by: Junhao Zou <zoujh99@qq.com>
213bda5 to
5245cd0
Compare
What type of PR is this?
/kind enhancement
What this PR does / why we need it:
The HAMi scheduler deep-copies the entire Pod cache on every
Filtercall, even though it only ever reads annotations and identity fields off those Pods. This PR replaces the whole-Pod deep copy with pointer sharing, while still copying the fields the manager owns.getNodesUsagecallsListPodsInfo()once perFilter.ListPodsInfocallsPodInfo.DeepCopy()for every cached GPU Pod, and that includescorev1.Pod.DeepCopy()— a full copy of the PodSpec, containers, env, volumes, status, and themanagedFields/FieldsV1the API server generates.getNodesUsagethen attaches each*PodInfoto the matching device'sDeviceUsage.PodInfos. When scoring runs per candidate node,scoreNodedeep-copies theNodeUsageagain — once for the app containers and once more per non-sidecar init container — and the oldDeviceUsage.DeepCopydeep-copied every attachedPodInfo, whole Pod included, a second time.So one scheduling attempt performs roughly:
whole-Pod copies. The product grows with both cluster size and GPU Pod count. Nothing on the scheduling path mutates those Pods.
The change
PodInfo.DeepCopy→PodInfo.Snapshot: still deep-copiesDevices(PodDevices) and the scalar fields the manager owns and rewrites in place, but shares thePodpointer.DeviceUsage.DeepCopy:slices.Clone(d.PodInfos)replaces the per-elementPodInfo.DeepCopy(). The copy gets its own slice header and shares the read-only*PodInfoentries.Net production change is those two spots, about 10 lines.
Performance validation
Environment: Apple M1 / 16 GiB / macOS 25.5.0 / Go 1.27.1 darwin/arm64
KWOK + fake-gpu-operator
GOMAXPROCS=4for both HAMi and kube-scheduler; HAMi withkube-qps=200,kube-burst=400, spread policy; kube-scheduler withpercentageOfNodesToScore: 100API server → kube-scheduler → HAMi Filter/Score → HAMi Bind → API server → KWOK Runningbefore-1 → after-1 → before-2 → after-2 → before-3 → after-3. Each round deletes its own Pods and restarts HAMi; resident Pods and nodes stay put.Steady-state results (3 rounds each, medians):
aa6f39dpprof:
aa6f39dalloc_space60.84 GiB → 4.59 GiB
68.69 → 10.03 CPU·s
benchmark:
BenchmarkListPodsInfo(pkg/device)BenchmarkScoreNode*(pkg/scheduler)ScoreNodeOccupiedpodsPerGPU=0 (control)ScoreNodeOccupiedpodsPerGPU=2ScoreNodeOccupiedpodsPerGPU=4ScoreNodeinitContainers=0/1/4 (control, idle devices)AI assistance disclosure
This PR was written with assistance from Claude Code, covering the code change, the benchmarks, and the setup and execution of the performance validation experiments. I have reviewed and understood every change line by line, and independently verified the correctness argument (the ownership boundary around the shared Pod and the read-only nature of each consumer).
Summary by CodeRabbit
Behavior Changes
Performance
Tests