Multithreading 为什么并发代码需要更多的时间来执行
我有一个名为线性化的函数…我试图加快它的执行速度,但惊讶地发现它变慢了。我是不是错过了什么,还是把基本原理搞乱了 据我所知,情况应该有所改善 谢谢Multithreading 为什么并发代码需要更多的时间来执行,multithreading,concurrency,go,Multithreading,Concurrency,Go,我有一个名为线性化的函数…我试图加快它的执行速度,但惊讶地发现它变慢了。我是不是错过了什么,还是把基本原理搞乱了 据我所知,情况应该有所改善 谢谢 package main import ( "fmt" "math" "sync" "time" ) var rgb []float64 func linearizeWithWg(v float64, idx int, wg *sync.WaitGroup) { defer wg.Done()
package main
import (
"fmt"
"math"
"sync"
"time"
)
var rgb []float64
func linearizeWithWg(v float64, idx int, wg *sync.WaitGroup) {
defer wg.Done()
if v <= 0.04045 {
rgb[idx] = v / 12.92
} else {
rgb[idx] = math.Pow((v+0.055)/1.055, 2.4)
}
}
func linearizeWithGoR(v float64) float64 {
res := make(chan float64)
go func(input float64) {
if input <= 0.04045 {
res <- input / 12.92
} else {
res <- math.Pow((input+0.055)/1.055, 2.4)
}
}(v)
return <-res
}
func linearizeNomal(v float64) float64 {
if v <= 0.04045 {
return v / 12.92
}
return math.Pow((v+0.055)/1.055, 2.4)
}
func main() {
start := time.Now()
const C = 1.0 / 255.0
//Normal Execution
for i := 0; i < 100000; i++ {
linearizeNomal(float64(i) * C * 0.5)
linearizeNomal(float64(i) * C * 1.5)
linearizeNomal(float64(i) * C * 4.5)
}
elaspsed := time.Since(start)
fmt.Println(elaspsed)
//With GoRoutines.. Slow
start = time.Now()
for i := 0; i < 100000; i++ {
linearizeWithGoR(float64(i) * C * 0.5)
linearizeWithGoR(float64(i) * C * 1.5)
linearizeWithGoR(float64(i) * C * 2.5)
}
elaspsed = time.Since(start)
fmt.Println(elaspsed)
//With WaitGroup. Slow
for i := 0; i < 100000; i++ {
rgb = make([]float64, 3)
var wg sync.WaitGroup
wg.Add(3)
linearizeWithWg(float64(i)*C*0.5, 0, &wg)
linearizeWithWg(float64(i)*C*1.5, 1, &wg)
linearizeWithWg(float64(i)*C*4.5, 2, &wg)
wg.Wait()
}
elaspsed = time.Since(start)
fmt.Println(elaspsed)
}
主程序包
进口(
“fmt”
“数学”
“同步”
“时间”
)
变量rgb[]浮点64
func-linearizeWithWg(v-float64,idx-int,wg*sync.WaitGroup){
推迟工作组完成()
如果v所有并发相关函数(通道创建、通道发送、goroutine创建)的开销远远大于在每个goroutine中执行的两条指令
此外,您的goroutine版本基本上是串行的,因为您生成一个goroutine并立即等待其通道的结果。waitgroup版本与此类似
使用少量goroutines重试,每个goroutines执行一个循环块。@Joker\u vD还有一个很好的观点,可以确保GOMAXPROCS
大于一个。您的问题是,您实际上没有同时执行任何操作
在工作组示例中,需要调用go-linearizeWithWg(…)
在goroutine示例中,您启动一个goroutine,然后等待它在函数中结束。要同时运行它,您需要一个缓冲响应通道,并让另一个goroutine获得响应确保您的GOMAXPROCS
大于1-否则,所有goroutine将在一个物理线程中执行在@Dean Elbaz注释后修改代码。并发不是并行。并发是思考代码的一种方式,而不是“这运行得更快”的同义词。尽管进行并发更正可能有助于使用所有内核。感谢您指出最大的错误…我确实纠正了这一错误,而且我再次看到使用*wg执行它没有什么大的好处…以下是一些快速统计数据…正常执行需要..38.ms和修改了wg tooks 1.82s的代码,因为我还添加了代码nCPU:=runtime.numpu()runtime.GOMAXPROCS(nCPU)
是否有@inf建议的开销?是的,开销是可能的。如果有大量来回的上下文切换,那么开销会很高。如果并行例程每个都进行更大的、长时间运行的计算/处理,那么并行运行更有意义。小部分处理,然后需要另一个线程的同步可能会非常困难慢点。