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

improve bin-packing performance #652

Merged
merged 4 commits into from
Sep 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion pkg/controllers/allocation/binpacking/packable.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,13 +87,18 @@ func PackableFor(i cloudprovider.InstanceType) *Packable {

// Pack attempts to pack the pods into capacity, keeping track of previously
// packed pods. If the capacity cannot fit the pod, they are set aside.
// Pods must be sorted in descending order.
func (p *Packable) Pack(pods []*v1.Pod) *Result {
result := &Result{}
for _, pod := range pods {
for i, pod := range pods {
if ok := p.reservePod(pod); ok {
result.packed = append(result.packed, pod)
continue
}
if p.fits(pods[len(pods)-1]) {
result.unpacked = append(result.unpacked, pods[i:]...)
return result
}
// if largest pod can't be packed, set it aside
if len(result.packed) == 0 {
result.unpacked = append(result.unpacked, pods...)
Expand All @@ -104,6 +109,19 @@ func (p *Packable) Pack(pods []*v1.Pod) *Result {
return result
}

// fits checks if the reserved resources + the pod overflows the total resources available.s
func (p *Packable) fits(pod *v1.Pod) bool {
minResourceList := resources.RequestsForPods(pod)
for resourceName, totalQuantity := range p.total {
reservedQuantity := p.reserved[resourceName].DeepCopy()
reservedQuantity.Add(minResourceList[resourceName])
if !totalQuantity.IsZero() && reservedQuantity.Cmp(totalQuantity) >= 0 {
return true
}
}
return false
}

func (p *Packable) reserve(requests v1.ResourceList) bool {
candidate := resources.Merge(p.reserved, requests)
// If any candidate resource exceeds total, fail to reserve
Expand Down
3 changes: 2 additions & 1 deletion pkg/controllers/allocation/binpacking/packer.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,9 @@ func sortByResources(instanceTypes []cloudprovider.InstanceType) {
func weightOf(instanceType cloudprovider.InstanceType) float64 {
return euclidean(
float64(instanceType.CPU().Value()),
float64(instanceType.Memory().ScaledValue(resource.Mega)), // 1 gb = 1 cpu
float64(instanceType.Memory().ScaledValue(resource.Giga)), // 1 gb = 1 cpu
float64(instanceType.NvidiaGPUs().Value())*1000, // Heavily weigh gpus x 1000
float64(instanceType.AMDGPUs().Value())*1000, // Heavily weigh gpus x1000
float64(instanceType.AWSNeurons().Value())*1000, // Heavily weigh neurons x1000
)
}
Expand Down