Golang如何高效利用多核与多线程
Golang如何高效利用多核与多线程 大家好,
我有一台配备64核/128线程的Threadripper Pro处理器。目前我的脚本仅利用了部分核心,而让其余核心处于空闲状态。有没有什么方法可以完全榨干CPU的性能?
谢谢。
4 回复
目前我的脚本只利用了核心,而让其余部分闲置
你能澄清一下你这是什么意思吗?
抱歉。我有128个虚拟处理器,但它只使用了64个。

在Go中充分利用多核的关键在于合理使用goroutine和并行处理。以下是一些高效利用多核CPU的技术方案:
1. 设置GOMAXPROCS
默认情况下Go会使用所有可用CPU核心,但可以通过以下方式显式设置:
runtime.GOMAXPROCS(128) // 设置为线程数
2. 使用Worker Pool模式
避免创建过多goroutine,使用固定数量的worker处理任务:
package main
import (
"fmt"
"runtime"
"sync"
)
func worker(id int, jobs <-chan int, results chan<- int, wg *sync.WaitGroup) {
defer wg.Done()
for job := range jobs {
// 执行CPU密集型计算
result := job * 2
results <- result
}
}
func main() {
numWorkers := 128 // 与线程数匹配
numJobs := 10000
jobs := make(chan int, numJobs)
results := make(chan int, numJobs)
var wg sync.WaitGroup
// 启动worker
for w := 1; w <= numWorkers; w++ {
wg.Add(1)
go worker(w, jobs, results, &wg)
}
// 分发任务
for j := 1; j <= numJobs; j++ {
jobs <- j
}
close(jobs)
// 等待所有worker完成
wg.Wait()
close(results)
}
3. 使用sync.Map进行并行处理
package main
import (
"sync"
"time"
)
func processData(data []int) map[int]int {
var m sync.Map
var wg sync.WaitGroup
for _, value := range data {
wg.Add(1)
go func(v int) {
defer wg.Done()
// CPU密集型计算
result := v * v
m.Store(v, result)
}(value)
}
wg.Wait()
// 转换回普通map
result := make(map[int]int)
m.Range(func(key, value interface{}) bool {
result[key.(int)] = value.(int)
return true
})
return result
}
4. 使用并行算法库
package main
import (
"github.com/golang/sync/errgroup"
"golang.org/x/sync/semaphore"
)
func parallelProcessing() {
var g errgroup.Group
sem := semaphore.NewWeighted(128) // 限制并发数
for i := 0; i < 1000; i++ {
g.Go(func() error {
// 获取信号量
if err := sem.Acquire(context.Background(), 1); err != nil {
return err
}
defer sem.Release(1)
// 执行计算
heavyComputation()
return nil
})
}
if err := g.Wait(); err != nil {
panic(err)
}
}
5. 使用runtime包监控CPU使用
package main
import (
"fmt"
"runtime"
"time"
)
func monitorCPU() {
go func() {
for {
var m runtime.MemStats
runtime.ReadMemStats(&m)
fmt.Printf("Goroutines: %d, CPUs: %d\n",
runtime.NumGoroutine(),
runtime.NumCPU())
time.Sleep(time.Second)
}
}()
}
6. 使用pprof分析性能
package main
import (
"net/http"
_ "net/http/pprof"
)
func main() {
// 启动pprof服务器
go func() {
http.ListenAndServe("localhost:6060", nil)
}()
// 你的主程序逻辑
}
对于64核/128线程的Threadripper Pro,建议:
- 使用worker pool模式,worker数量设置为128
- 确保任务足够细粒度以充分利用所有核心
- 避免goroutine间的锁竞争
- 使用无锁数据结构如sync.Map
- 定期使用pprof分析CPU使用情况
通过以上方法,可以最大化利用Threadripper Pro的多核性能。

