Performance Golang goroutine在添加并发时会减慢速度

Performance Golang goroutine在添加并发时会减慢速度,performance,go,concurrency,goroutine,Performance,Go,Concurrency,Goroutine,我正在学习golang和goroutine的用法。 有了这个示例代码,在我有4个逻辑CPU的PC上,我无法理解为什么我没有任何性能改进 如果我添加并发性,那么在没有并发性的情况下,所需的时间往往会比原来的慢 2017/10/27 13:57:17 Starting 1 threads 2017/10/27 13:57:27 Id routine: 0 rate: 232.558140 2017/10/27 13:57:27 Current total rate was 232.56 K/s 2

我正在学习golang和goroutine的用法。
有了这个示例代码,在我有4个逻辑CPU的PC上,我无法理解为什么我没有任何性能改进

如果我添加并发性,那么在没有并发性的情况下,所需的时间往往会比原来的慢

2017/10/27 13:57:17 Starting 1 threads
2017/10/27 13:57:27 Id routine: 0  rate: 232.558140
2017/10/27 13:57:27 Current total rate was 232.56 K/s
2017/10/27 13:57:27 Starting 1 threads
2017/10/27 13:57:37 Id routine: 0  rate: 357.142857
2017/10/27 13:57:37 Current total rate was 357.14 K/s


2017/10/27 13:58:04 Starting 2 threads
2017/10/27 13:58:14 Id routine: 0  rate: 131.578947
2017/10/27 13:58:14 Id routine: 1  rate: 129.870130
2017/10/27 13:58:14 Current total rate was 261.45 K/s
2017/10/27 13:58:14 Starting 2 threads
2017/10/27 13:58:24 Id routine: 1  rate: 144.927536
2017/10/27 13:58:24 Id routine: 0  rate: 151.515152
2017/10/27 13:58:24 Current total rate was 296.44 K/s

2017/10/27 13:59:15 Starting 3 threads
2017/10/27 13:59:25 Id routine: 2  rate: 94.339623
2017/10/27 13:59:25 Id routine: 0  rate: 92.592593
2017/10/27 13:59:25 Id routine: 1  rate: 90.090090
2017/10/27 13:59:25 Current total rate was 277.02 K/s
2017/10/27 13:59:25 Starting 3 threads
2017/10/27 13:59:35 Id routine: 2  rate: 92.592593
2017/10/27 13:59:35 Id routine: 0  rate: 90.090090
2017/10/27 13:59:35 Id routine: 1  rate: 101.010101
2017/10/27 13:59:35 Current total rate was 283.69 K/s

2017/10/27 14:00:12 Starting 4 threads
2017/10/27 14:00:22 Id routine: 1  rate: 56.818182
2017/10/27 14:00:22 Id routine: 3  rate: 56.818182
2017/10/27 14:00:22 Id routine: 0  rate: 61.349693
2017/10/27 14:00:22 Id routine: 2  rate: 62.500000
2017/10/27 14:00:22 Current total rate was 237.49 K/s
2017/10/27 14:00:22 Starting 4 threads
2017/10/27 14:00:32 Id routine: 1  rate: 67.114094
2017/10/27 14:00:32 Id routine: 3  rate: 61.349693
2017/10/27 14:00:32 Id routine: 0  rate: 57.803468
2017/10/27 14:00:32 Id routine: 2  rate: 65.789474
2017/10/27 14:00:32 Current total rate was 252.06 K/s
下面是goroutines的并发代码:

package main

import (
    "fmt"
    "log"
    "sync"
    "time"
)

var (
    tryArr           []string
    goroutineQuit    = make(chan struct{})
    concurrencyMapHQ = struct {
        sync.RWMutex
        HQ map[int]float64
    }{HQ: make(map[int]float64)}
)

func rateStats() {
    var totalRate float64
    for i, rate := range concurrencyMapHQ.HQ {
        log.Printf("Id routine: %d  rate: %f", i, rate)
        totalRate += rate
    }

    log.Printf("Current total rate was %.2f K/s", totalRate)
}

func stopThreads(threads int) {
    for i := 0; i < threads; i++ {
        goroutineQuit <- struct{}{}
    }

    rateStats()
}

func runThreads(threads int, steps int) {
    log.Printf("Starting %d threads", threads)

    for i := 0; i < threads; i++ {
        i := i
        go func(id int, steps int) {
            calculate(i, steps)
        }(i, steps)
    }
}

func calculate(idRoutine int, steps int) {
    var (
        possibles []string
        numBatchs = 0
        t1        = time.Now()
    )

    for {
        select {
        case <-goroutineQuit:
            return
        default:
            possibles = nil

            for _, nonce := range tryArr {
                possibles = append(possibles, nonce)
            }

            numBatchs++
            if numBatchs == 99 {
                t2 := time.Now()

                timeExecution := t2.Sub(t1) / time.Millisecond

                concurrencyMapHQ.Lock()
                concurrencyMapHQ.HQ[idRoutine] = float64(steps) / float64(timeExecution)
                concurrencyMapHQ.Unlock()

                numBatchs = 0
                t1 = t2

            }
        }
    }
}

func main() {
    threads := 4
    steps := 10000

    tryArr = make([]string, steps)
    for i := 0; i < steps; i++ {
        tryArr[i] = fmt.Sprintf("indice: %d", i)
    }

    for {
        runThreads(threads, steps)
        time.Sleep(10 * time.Second)
        stopThreads(threads)

        runThreads(threads, steps)
        time.Sleep(10 * time.Second)
        stopThreads(threads)
    }
}
主程序包
进口(
“fmt”
“日志”
“同步”
“时间”
)
变量(
tryArr[]字符串
goroutineQuit=make(chan结构{})
concurrencyMapHQ=struct{
sync.RWMutex
总部地图[int]64
}{HQ:make(map[int]float64)}
)
func ratests(){
var总利率浮动64
对于i,速率:=范围并发数phq.HQ{
log.Printf(“Id例程:%d速率:%f”,i,速率)
总速率+=速率
}
log.Printf(“当前总速率为%.2f K/s”,总速率)
}
func停止线程(线程int){
对于i:=0;igoroutineQuit为
默认情况分配
可能的

default:
    //possibles = nil
    possibles = make([]string, 0, len(tryArr))
例如,
possibles=nil

2017/10/27 10:59:35 GOMAXPROCS: 4
2017/10/27 10:59:35 Starting 4 threads
2017/10/27 10:59:45 Id routine: 3  rate: 20.576132
2017/10/27 10:59:45 Id routine: 2  rate: 21.276596
2017/10/27 10:59:45 Id routine: 0  rate: 19.960080
2017/10/27 10:59:45 Id routine: 1  rate: 21.276596
2017/10/27 10:59:45 Current total rate was 83.09 K/s
2017/10/27 10:59:45 Starting 4 threads
2017/10/27 10:59:55 Id routine: 2  rate: 20.533881
2017/10/27 10:59:55 Id routine: 0  rate: 20.576132
2017/10/27 10:59:55 Id routine: 1  rate: 19.801980
2017/10/27 10:59:55 Id routine: 3  rate: 20.746888
2017/10/27 10:59:55 Current total rate was 81.66 K/s
57.08user 2.16system 0:20.02elapsed 295%CPU
并且,
possibles=make([]字符串,0,len(tryArr))


你的结果是什么


随着“
threads
”[1,2,3,4]和
possibles=make([]字符串,0,len(tryArr))
的增加



总之,您似乎正在对Go垃圾回收器进行基准测试。垃圾回收不是免费的。请尽量减少分配。使用Go基准测试功能。

您是否分析了应用程序以了解时间花在哪里?如果您使用测试包从真正的基准测试开始,这会更容易。正如JimB提到的,pprof是一个很好的工具为了调试这类问题。我还建议使用trace捕获goroutine创建/阻止/取消阻止等执行事件。youtube频道justforfunc最近制作了一个教程视频,介绍如何使用该工具提高go程序的性能。正如JimB建议的,使用
golang
内置框架,而不是buil你自己的。它甚至涵盖了并行的基准。不是所有的都被并发改进了。它不是一个万能的魔法弹,它使事情发展得很快。你的GORATONE在中间运行一个非常紧密的循环,一个互斥锁。
2017/10/27 10:57:33 GOMAXPROCS: 4
2017/10/27 10:57:33 Starting 4 threads
2017/10/27 10:57:43 Id routine: 0  rate: 112.359551
2017/10/27 10:57:43 Id routine: 1  rate: 104.166667
2017/10/27 10:57:43 Id routine: 2  rate: 91.743119
2017/10/27 10:57:43 Id routine: 3  rate: 112.359551
2017/10/27 10:57:43 Current total rate was 420.63 K/s
2017/10/27 10:57:43 Starting 4 threads
2017/10/27 10:57:53 Id routine: 0  rate: 123.456790
2017/10/27 10:57:53 Id routine: 1  rate: 126.582278
2017/10/27 10:57:53 Id routine: 2  rate: 113.636364
2017/10/27 10:57:53 Id routine: 3  rate: 119.047619
2017/10/27 10:57:53 Current total rate was 482.72 K/s
58.11user 2.32system 0:20.01elapsed 302%CPU
$ cat /proc/cpuinfo | grep 'cpu cores' | uniq
cpu cores   : 4
2017/10/27 11:19:03 GOMAXPROCS: 4
2017/10/27 11:19:03 Starting 1 threads
2017/10/27 11:19:13 Id routine: 0  rate: 285.714286
2017/10/27 11:19:13 Current total rate was 285.71 K/s
2017/10/27 11:19:13 Starting 1 threads
2017/10/27 11:19:23 Id routine: 0  rate: 312.500000
2017/10/27 11:19:23 Current total rate was 312.50 K/s
24.66user 1.13system 0:20.01elapsed 128%CPU
2017/10/27 11:19:28 GOMAXPROCS: 4
2017/10/27 11:19:28 Starting 2 threads
2017/10/27 11:19:38 Id routine: 0  rate: 238.095238
2017/10/27 11:19:38 Id routine: 1  rate: 217.391304
2017/10/27 11:19:38 Current total rate was 455.49 K/s
2017/10/27 11:19:38 Starting 2 threads
2017/10/27 11:19:48 Id routine: 1  rate: 192.307692
2017/10/27 11:19:48 Id routine: 0  rate: 217.391304
2017/10/27 11:19:48 Current total rate was 409.70 K/s
46.14user 2.07system 0:20.00elapsed 240%CPU
2017/10/27 11:19:53 GOMAXPROCS: 4
2017/10/27 11:19:53 Starting 3 threads
2017/10/27 11:20:03 Id routine: 2  rate: 142.857143
2017/10/27 11:20:03 Id routine: 1  rate: 149.253731
2017/10/27 11:20:03 Id routine: 0  rate: 147.058824
2017/10/27 11:20:03 Current total rate was 439.17 K/s
2017/10/27 11:20:03 Starting 3 threads
2017/10/27 11:20:13 Id routine: 2  rate: 153.846154
2017/10/27 11:20:13 Id routine: 1  rate: 156.250000
2017/10/27 11:20:13 Id routine: 0  rate: 153.846154
2017/10/27 11:20:13 Current total rate was 463.94 K/s
52.41user 2.21system 0:20.01elapsed 273%CPU
2017/10/27 11:20:25 GOMAXPROCS: 4
2017/10/27 11:20:25 Starting 4 threads
2017/10/27 11:20:35 Id routine: 1  rate: 106.382979
2017/10/27 11:20:35 Id routine: 2  rate: 102.040816
2017/10/27 11:20:35 Id routine: 0  rate: 125.000000
2017/10/27 11:20:35 Id routine: 3  rate: 117.647059
2017/10/27 11:20:35 Current total rate was 451.07 K/s
2017/10/27 11:20:35 Starting 4 threads
2017/10/27 11:20:45 Id routine: 1  rate: 111.111111
2017/10/27 11:20:45 Id routine: 2  rate: 112.359551
2017/10/27 11:20:45 Id routine: 0  rate: 119.047619
2017/10/27 11:20:45 Id routine: 3  rate: 128.205128
2017/10/27 11:20:45 Current total rate was 470.72 K/s
58.80user 2.20system 0:20.01elapsed 304%CPU