为什么在make([] int,14)中有一个runtime.morestack但在make([] int,13)中没有?

我已经知道 runtime.morestack </ code>会导致goroutine上下文切换(如果 </ p>

当我对此做一些实验时,我发现了一个有趣的事实。</ p>

< p>比较以下代码。</ p>

  func main(){
_ = make([] int,13)
}
</ code> </ pre >


  func main(){
_ = make([] int,14)
}
</ code> </ pre>

并通过运行以下命令进行编译:(在go1.9和go 1.11中进行了尝试</ p>

  $ go build -gcflags“ -S -l -N  “ x.go 
</ code> </ pre>

您可能会发现一个主要区别是,第一个输出包含 CALL runtime.morestack_noctxt(SB)</ code>,而第二个则不包含 </ p>

我想这是一种优化,但是为什么呢?</ p>
</ div>

展开原文

原文

I've already known that the runtime.morestack will cause goroutine context switch (If the sysmon goroutine has marked it "has to switch").

And when I do some experiment around this, I've found an interesting fact.

Compare the following codes.

func main() {
    _ = make([]int, 13)
}

func main() {
    _ = make([]int, 14)
}

And compile them by running the following command: (Tried in go1.9 and go 1.11)

$ go build -gcflags "-S -l -N" x.go

You may find a major difference that the first outputs contains CALL runtime.morestack_noctxt(SB) while the second doesn't.

I guess it is an optimization, but why?

doudun1934
doudun1934 谢谢你的链接!确实对我有很大帮助。
一年多之前 回复
douhuanchi6586
douhuanchi6586 该系列可能会启发blog.altoros.com/…
一年多之前 回复

1个回答

Finally, I got the answer.

  • Making a slice that less than 65,536 bytes and not escaped from the func will be allocated in the stack, not the heap.

  • StackGuard0 will be higher than the stack's lowest address by at least 128 bytes. (Even after downsizing)

  • make([]int, 13) will allocate 128 bytes memories in total.

sizeof(struct slice) + 13 * 8 = 24 + 104 = 128.

So the answer is clear, this is an optimization for amd64.

For a leaf function, if it used less than 128 bytes memories, the compiler wouldn't generate codes that checking if the stack is overflowed (because there are enough spaces).

Here is the explanation in go/src/runtime/stack.go

The per-goroutine g->stackguard is set to point StackGuard bytes above the bottom of the stack. Each function compares its stack pointer against g->stackguard to check for overflow. To cut one instruction from the check sequence for functions with tiny frames, the stack is allowed to protrude StackSmall bytes below the stack guard. Functions with large frames don't bother with the check and always call morestack. The sequences are (for amd64, others are similar):

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐