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建议的开销?是的,开销是可能的。如果有大量来回的上下文切换,那么开销会很高。如果并行例程每个都进行更大的、长时间运行的计算/处理,那么并行运行更有意义。小部分处理,然后需要另一个线程的同步可能会非常困难慢点。