有关 Golang 多线程对数组操作时的性能问题
資深大佬 : vcfghtyjc 43
我尝试着用多线程分别运行以下两个函数,并使用 time
来查看它们的 cpu 使用率,一个的使用率就符合启动的线程数(比如 8 线程就得到 800% 的使用率),另一个就无法得到相符合的 cpu 使用率 (比如 8 线程得到 600% 的使用率,2 线程得到 300% 的使用率)。虽然两个函数都没有线程间的互斥锁,这两个函数的区别在于:第一个函数没有对数组的操作,第二个函数有对数组的操作。具体函数如下:
函数 1: addOne
该函数持续做加法运算
func addOne(n int,wg *sync.WaitGroup){ var i int for i < n{ i++ } wg.Done() }
函数 2: appendArray
该函数不断向一个数组中添加元素,为了防止内存溢出,每添加 10,000 个元素,就清空数组。
func appendArray(n int,wg *sync.WaitGroup){ var i int list := make([]int,10000) for i < n{ for j := 0 ; j < 10000; j++{ list = append(list, i) } list = make([]int,10000) i++ } wg.Done() }
启动多线程的函数: test
该函数将工作总数 totalJobs
平分给每个线程
func test(totalThreads, totalJobs int){ n := totalJobs/totalThreads var wg sync.WaitGroup for i := 0; i < totalThreads; i++{ wg.Add(1) go appendArray(n,&wg) // go addOne(n,&wg) } wg.Wait() }
通过使用 pprof
, 两个代码的 cpu 分析如下:
函数 1:
函数 2:
我发现对于第二个函数,虽然代码中没有调用锁,在执行的过程中会出现 runtime lock
, runtime futex
之类的锁操作。
这里我不明白的是:
- 为什么在有数组操作后,编译后的程序出现了锁操作,从而影响力 cpu 的使用?
- 如何避免 /减缓这些锁操作带来的性能影响?
大佬有話說 (17)