Skip to content

Go调度性能优化 - Golang调度器优化实战

调度器性能直接影响Go程序的并发性能。掌握调度优化技巧对于构建高性能Go应用至关重要。

📋 核心优化策略

优化要点总结

  1. GOMAXPROCS设置: 合理配置P的数量
  2. Goroutine池化: 复用goroutine减少创建开销
  3. 亲和性优化: 利用P的本地队列特性
  4. 负载均衡: 避免工作窃取开销
go
package main

import (
    "fmt"
    "runtime"
    "sync"
    "time"
)

func main() {
    fmt.Println("=== Go调度性能优化 ===")
    
    // 1. GOMAXPROCS优化
    fmt.Printf("\n--- GOMAXPROCS优化 ---\n")
    cpus := runtime.NumCPU()
    fmt.Printf("CPU核心数: %d\n", cpus)
    
    // 对于CPU密集型任务,设置为CPU数量
    runtime.GOMAXPROCS(cpus)
    fmt.Printf("设置GOMAXPROCS: %d\n", cpus)
    
    // 2. Goroutine池化
    fmt.Printf("\n--- Goroutine池化 ---\n")
    
    type WorkerPool struct {
        tasks   chan func()
        workers int
        wg      sync.WaitGroup
    }
    
    func NewWorkerPool(workers int) *WorkerPool {
        pool := &WorkerPool{
            tasks:   make(chan func(), workers*2),
            workers: workers,
        }
        
        for i := 0; i < workers; i++ {
            pool.wg.Add(1)
            go pool.worker()
        }
        
        return pool
    }
    
    func (p *WorkerPool) worker() {
        defer p.wg.Done()
        for task := range p.tasks {
            task()
        }
    }
    
    func (p *WorkerPool) Submit(task func()) {
        p.tasks <- task
    }
    
    func (p *WorkerPool) Close() {
        close(p.tasks)
        p.wg.Wait()
    }
    
    // 使用worker pool
    pool := NewWorkerPool(runtime.NumCPU())
    
    start := time.Now()
    for i := 0; i < 10000; i++ {
        id := i
        pool.Submit(func() {
            _ = id * 2
        })
    }
    pool.Close()
    fmt.Printf("Worker Pool完成10000任务,耗时: %v\n", time.Since(start))
    
    // 3. 避免过度并发
    fmt.Printf("\n--- 并发控制 ---\n")
    
    sem := make(chan struct{}, 100) // 限制并发数为100
    var wg sync.WaitGroup
    
    start = time.Now()
    for i := 0; i < 10000; i++ {
        wg.Add(1)
        sem <- struct{}{} // 获取信号量
        
        go func(id int) {
            defer func() {
                <-sem // 释放信号量
                wg.Done()
            }()
            _ = id * 2
        }(i)
    }
    wg.Wait()
    fmt.Printf("限流并发完成10000任务,耗时: %v\n", time.Since(start))
    
    fmt.Printf("\n📋 优化建议:\n")
    fmt.Printf("1. CPU密集: GOMAXPROCS = CPU核心数\n")
    fmt.Printf("2. I/O密集: 可适当增加GOMAXPROCS\n")
    fmt.Printf("3. 使用Worker Pool复用goroutine\n")
    fmt.Printf("4. 限制并发数避免调度开销\n")
    fmt.Printf("5. 批量处理减少goroutine创建\n")
}

🎯 关键优化点

  1. GOMAXPROCS调优: 根据工作负载特性设置
  2. 池化复用: Worker Pool模式减少创建销毁
  3. 并发控制: 使用信号量限制goroutine数量
  4. 批量处理: 减少细粒度并发的调度开销

正在精进