V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  lichundian  ›  全部回复第 1 页 / 共 1 页
回复总数  2
2015-09-26 16:26:46 +08:00
回复了 oscarzhao 创建的主题 Go 编程语言 golang 小程序,多核 CPU 均跑到 100%
2015-09-26 16:25:44 +08:00
回复了 oscarzhao 创建的主题 Go 编程语言 golang 小程序,多核 CPU 均跑到 100%
@nekoyaki @zhuang @wwek @oscarzhao
出现没有跑满 CPU 的原因是: rand.Intn()方法会调用一个全局对象的方法生成随机数,这个全局方法是有 lock 的,所以会出现 golang 的多个 goroutine 相互竞争, lock 的底层实现,我不是很清楚,但是“ lock 检测不让 CPU 满载”是高并发程序的基本原则。要想让其满载,应该使用 goroutine 独立的计算模块,最简单就是
for {} .
见: https://golang.org/src/math/rand/rand.go#L238
238 func (r *lockedSource) Int63() (n int64) {
239 r.lk.Lock()
240 n = r.src.Int63()
241 r.lk.Unlock()
242 return
243 }

另外作者程序存在两个问题:
1. main 线程调用的计算和其他线程调用的计算不一样, main 线程会占用 100%,而其他线程并不会满负载。其 CPU 的负载结果很难说是平均每个线程的负载情况。
2. Golang 映射的 native 的线程数可以通过 runtime.GOMAXPROCS(cpunum)设置,实际运行中最大的线程数在此基础上+1 ,因为还有 gc 线程。作者为了测试 routineNum 满载,除了 main 线程外,应该再开启 routineNum-1 个 goroutine 。

我做了两个测试,硬件配置: 2CPU, 4 cores per CPU; Golang 配置: runtime.GOMAXPROCS(8):
1.
func main() {
routineNum, err := strconv.Atoi(os.Args(1))

cpunum := runtime.NumCPU()
runtime.GOMAXPROCS(cpunum)
for i := 0; i < routineNum -1 ; i += 1 {
go func() {
for {
rand.Intn(10000000)
}
}()
}
for {
rand.Intn(10000000)
}
}
以下是测试结果
routineNum 1 2 3 4 5 6 7 8
CPU 使用率 100% 120% 201% 210% 220% 240% 266% 290%
#native thread 4 5 6 6 7 8 9 9

2.
func main() {
routineNum, err := strconv.Atoi(os.Args(1))

cpunum := runtime.NumCPU()
runtime.GOMAXPROCS(cpunum)
for i := 0; i < routineNum -1 ; i += 1 {
go func() {
for {
// nothing
}
}()
}
for {
// nothing
}
}
routineNum 1 2 3 4 5 6 7 8
CPU 使用率 100% 199% 299% 399% 496% 597% 697% 790%
#native threads 4 4 5 6 7 8 9 9

所以楼上说 Golang 没有跑到满负载是做了什么优化是错误的,另外不同版本之间的差别只是因为 lock 的性能差别导致;内核调度器的实现不会这么傻,在 core 处于 idle 的时候难道不将计算密集型的线程分配在上面?

所以楼主想实现制定的运行百分比,就应该摒弃采用 rand 计算的方法。而采取独立的计算方法。例如 for 循环满足一定条件就睡觉,当然还得事先计算好一定时间内会计算多少条语句,编程之美第一道题就是这个,作者去脑补吧。^_^
关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   921 人在线   最高记录 6679   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 10ms · UTC 20:59 · PVG 04:59 · LAX 12:59 · JFK 15:59
Developed with CodeLauncher
♥ Do have faith in what you're doing.