mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-04 04:08:16 +00:00 
			
		
		
		
	Merge pull request #67555 from wgliang/opt/improve-performance
Automatic merge from submit-queue (batch tested with PRs 67555, 68196). If you want to cherry-pick this change to another branch, please follow the instructions here: https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md. Not split nodes when searching for nodes but doing it all at once **What this PR does / why we need it**: Not split nodes when searching for nodes but doing it all at once. **Which issue(s) this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close the issue(s) when PR gets merged)*: Fixes # **Special notes for your reviewer**: @bsalamat This is a follow up PR of #66733. https://github.com/kubernetes/kubernetes/pull/66733#discussion_r205932531 **Release note**: ```release-note Not split nodes when searching for nodes but doing it all at once. ```
This commit is contained in:
		@@ -17,6 +17,7 @@ limitations under the License.
 | 
				
			|||||||
package core
 | 
					package core
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"context"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"math"
 | 
						"math"
 | 
				
			||||||
	"sort"
 | 
						"sort"
 | 
				
			||||||
@@ -373,16 +374,19 @@ func (g *genericScheduler) findNodesThatFit(pod *v1.Pod, nodes []*v1.Node) ([]*v
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		// Create filtered list with enough space to avoid growing it
 | 
							// Create filtered list with enough space to avoid growing it
 | 
				
			||||||
		// and allow assigning.
 | 
							// and allow assigning.
 | 
				
			||||||
		filtered = make([]*v1.Node, 2*numNodesToFind)
 | 
							filtered = make([]*v1.Node, numNodesToFind)
 | 
				
			||||||
		errs := errors.MessageCountMap{}
 | 
							errs := errors.MessageCountMap{}
 | 
				
			||||||
		var predicateResultLock sync.Mutex
 | 
							var (
 | 
				
			||||||
		var filteredLen int32
 | 
								predicateResultLock sync.Mutex
 | 
				
			||||||
 | 
								filteredLen         int32
 | 
				
			||||||
 | 
								equivClass          *equivalence.Class
 | 
				
			||||||
 | 
							)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							ctx, cancel := context.WithCancel(context.Background())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// We can use the same metadata producer for all nodes.
 | 
							// We can use the same metadata producer for all nodes.
 | 
				
			||||||
		meta := g.predicateMetaProducer(pod, g.cachedNodeInfoMap)
 | 
							meta := g.predicateMetaProducer(pod, g.cachedNodeInfoMap)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		var equivClass *equivalence.Class
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if g.equivalenceCache != nil {
 | 
							if g.equivalenceCache != nil {
 | 
				
			||||||
			// getEquivalenceClassInfo will return immediately if no equivalence pod found
 | 
								// getEquivalenceClassInfo will return immediately if no equivalence pod found
 | 
				
			||||||
			equivClass = equivalence.NewClass(pod)
 | 
								equivClass = equivalence.NewClass(pod)
 | 
				
			||||||
@@ -412,25 +416,24 @@ func (g *genericScheduler) findNodesThatFit(pod *v1.Pod, nodes []*v1.Node) ([]*v
 | 
				
			|||||||
				return
 | 
									return
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if fits {
 | 
								if fits {
 | 
				
			||||||
				filtered[atomic.AddInt32(&filteredLen, 1)-1] = g.cachedNodeInfoMap[nodeName].Node()
 | 
									length := atomic.AddInt32(&filteredLen, 1)
 | 
				
			||||||
 | 
									if length > numNodesToFind {
 | 
				
			||||||
 | 
										cancel()
 | 
				
			||||||
 | 
										atomic.AddInt32(&filteredLen, -1)
 | 
				
			||||||
 | 
									} else {
 | 
				
			||||||
 | 
										filtered[length-1] = g.cachedNodeInfoMap[nodeName].Node()
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				predicateResultLock.Lock()
 | 
									predicateResultLock.Lock()
 | 
				
			||||||
				failedPredicateMap[nodeName] = failedPredicates
 | 
									failedPredicateMap[nodeName] = failedPredicates
 | 
				
			||||||
				predicateResultLock.Unlock()
 | 
									predicateResultLock.Unlock()
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		numNodesProcessed := int32(0)
 | 
					
 | 
				
			||||||
		for numNodesProcessed < allNodes {
 | 
							// Stops searching for more nodes once the configured number of feasible nodes
 | 
				
			||||||
			numNodesToProcess := allNodes - numNodesProcessed
 | 
							// are found.
 | 
				
			||||||
			if numNodesToProcess > numNodesToFind {
 | 
							workqueue.ParallelizeUntil(ctx, 16, int(allNodes), checkNode)
 | 
				
			||||||
				numNodesToProcess = numNodesToFind
 | 
					
 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			workqueue.Parallelize(16, int(numNodesToProcess), checkNode)
 | 
					 | 
				
			||||||
			if filteredLen >= numNodesToFind {
 | 
					 | 
				
			||||||
				break
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			numNodesProcessed += numNodesToProcess
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		filtered = filtered[:filteredLen]
 | 
							filtered = filtered[:filteredLen]
 | 
				
			||||||
		if len(errs) > 0 {
 | 
							if len(errs) > 0 {
 | 
				
			||||||
			return []*v1.Node{}, FailedPredicateMap{}, errors.CreateAggregateFromMessageCountMap(errs)
 | 
								return []*v1.Node{}, FailedPredicateMap{}, errors.CreateAggregateFromMessageCountMap(errs)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,6 +17,7 @@ limitations under the License.
 | 
				
			|||||||
package workqueue
 | 
					package workqueue
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"context"
 | 
				
			||||||
	"sync"
 | 
						"sync"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	utilruntime "k8s.io/apimachinery/pkg/util/runtime"
 | 
						utilruntime "k8s.io/apimachinery/pkg/util/runtime"
 | 
				
			||||||
@@ -24,9 +25,20 @@ import (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
type DoWorkPieceFunc func(piece int)
 | 
					type DoWorkPieceFunc func(piece int)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Parallelize is a very simple framework that allow for parallelizing
 | 
					// Parallelize is a very simple framework that allows for parallelizing
 | 
				
			||||||
// N independent pieces of work.
 | 
					// N independent pieces of work.
 | 
				
			||||||
func Parallelize(workers, pieces int, doWorkPiece DoWorkPieceFunc) {
 | 
					func Parallelize(workers, pieces int, doWorkPiece DoWorkPieceFunc) {
 | 
				
			||||||
 | 
						ParallelizeUntil(nil, workers, pieces, doWorkPiece)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ParallelizeUntil is a framework that allows for parallelizing N
 | 
				
			||||||
 | 
					// independent pieces of work until done or the context is canceled.
 | 
				
			||||||
 | 
					func ParallelizeUntil(ctx context.Context, workers, pieces int, doWorkPiece DoWorkPieceFunc) {
 | 
				
			||||||
 | 
						var stop <-chan struct{}
 | 
				
			||||||
 | 
						if ctx != nil {
 | 
				
			||||||
 | 
							stop = ctx.Done()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	toProcess := make(chan int, pieces)
 | 
						toProcess := make(chan int, pieces)
 | 
				
			||||||
	for i := 0; i < pieces; i++ {
 | 
						for i := 0; i < pieces; i++ {
 | 
				
			||||||
		toProcess <- i
 | 
							toProcess <- i
 | 
				
			||||||
@@ -44,7 +56,12 @@ func Parallelize(workers, pieces int, doWorkPiece DoWorkPieceFunc) {
 | 
				
			|||||||
			defer utilruntime.HandleCrash()
 | 
								defer utilruntime.HandleCrash()
 | 
				
			||||||
			defer wg.Done()
 | 
								defer wg.Done()
 | 
				
			||||||
			for piece := range toProcess {
 | 
								for piece := range toProcess {
 | 
				
			||||||
				doWorkPiece(piece)
 | 
									select {
 | 
				
			||||||
 | 
									case <-stop:
 | 
				
			||||||
 | 
										return
 | 
				
			||||||
 | 
									default:
 | 
				
			||||||
 | 
										doWorkPiece(piece)
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}()
 | 
							}()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user