【发布时间】:2021-07-09 13:21:04
【问题描述】:
我阅读了 Go 的并发模型,也看到了并发和并行之间的区别。为了测试并行执行,我写了如下程序。
package main
import (
"fmt"
"runtime"
"time"
)
const count = 1e8
var buffer [count]int
func main() {
fmt.Println("GOMAXPROCS: ", runtime.GOMAXPROCS(0))
// Initialise with dummy value
for i := 0; i < count; i++ {
buffer[i] = 3
}
// Sequential operation
now := time.Now()
worker(0, count-1)
fmt.Println("sequential operation: ", time.Since(now))
// Attempt to parallelize
ch := make(chan int, 1)
now = time.Now()
go func() {
worker(0, (count/2)-1)
ch <- 1
}()
worker(count/2, count-1)
<-ch
fmt.Println("parallel operation: ", time.Since(now))
}
func worker(start int, end int) {
for i := start; i <= end; i++ {
task(i)
}
}
func task(index int) {
buffer[index] = 2 * buffer[index]
}
但问题是:结果不是很讨喜。
GOMAXPROCS: 8
sequential operation: 206.85ms
parallel operation: 169.028ms
使用 goroutine 确实可以加快速度,但还不够。我预计它会接近两倍的速度。我的代码和/或理解有什么问题?我怎样才能接近两倍的速度?
【问题讨论】:
-
您正在并行化一个极其微不足道的操作。考虑到并发的开销超过了进行单个整数乘法所需的时间,我对此感到惊讶。
-
@Adrian 感谢您指出这一点。使用更复杂的操作是否有可能在计算时间上提供更好的区分?我是否正确地并行化了操作?
-
是的,如果您将需要时间的工作并行化,并且有内核可以将其分散,那么您通常应该会看到性能提升。
标签: go concurrency