为什么会导致goroutine创建的测量时间差异?

时间:2017-02-04 08:39:03

标签: go

考虑以下应用程序,旨在衡量goroutine创建延迟。假设我们正在运行GOMAXPROCS=2

package main

import "fmt"
import "time"

const numRuns = 10000

type  timeRecord struct{
    Ts time.Time
    Msg string
}

var timeStamps []timeRecord

func threadMain(done chan bool) {
    timeStamps = append(timeStamps, timeRecord{time.Now(), "Inside thread"})
    done <- true
}

func main() {
    timeStamps = make([]timeRecord, 0, numRuns*2)
    done := make(chan bool)
    dummy := 0
    for i := 0; i < numRuns; i++ {
        timeStamps = append(timeStamps, timeRecord{time.Now(), "Before creation"})
        go threadMain(done)
        <-done
    }

    // Regularize
    regularizedTime := make([]time.Duration, numRuns*2)
    for i := 0; i < len(timeStamps) ; i++ {
        regularizedTime[i] = timeStamps[i].Ts.Sub(timeStamps[0].Ts)
    }

    // Fake timetraced
    fmt.Printf("%6d ns (+%6d ns): %s\n", 0, 0, timeStamps[0].Msg)
    for i := 1; i < len(timeStamps) ; i++ {
        fmt.Printf("%8d ns (+%6d ns): %s\n", regularizedTime[i], (regularizedTime[i] - regularizedTime[i-1]).Nanoseconds(), timeStamps[i].Msg)
    }
}

在我的服务器上,这始终从Before creationInside thread大致输出中值 260 ns delta 。现在考虑主要方法的以下变化。

timeStamps = make([]timeRecord, 0, numRuns*2)
done := make(chan bool)
dummy := 0
for i := 0; i < numRuns; i++ {
    timeStamps = append(timeStamps, timeRecord{time.Now(), "Before creation"})
    go threadMain(done)
    for j := 0; j < 1000; j++ {
        dummy += j
    }
    <-done
}

在此变化下,相同的时间delta大致 890 ns

显然,确切的数字是机器特定的,但数字之间的差异很奇怪。从逻辑上讲,如果我在&#34;之前测量&#34;在创建之前&#34;在&#34;内部线程&#34;中,在go语句之后添加额外的逻辑似乎不应该增加那个时间,但确实如此。

有没有人知道为什么在预期的位置没有发生时间增加?

1 个答案:

答案 0 :(得分:0)

Go调度程序是合作的。它可以仅在程序的某些点(例如函数调用,读/写通道等)将当前goroutine切换到另一个。我希望您观察到的差异是由于goroutine在以后启动(之后)添加for循环)。