2016-12-03 00:46
浏览 228


I was playing with golang 1.7.3 on MacBook and Ubuntu and found that runtime.GOMAXPROCS is limited to 256. Does anyone know where this limit comes from? Is this documented anywhere and why would there be a limit? Is this an implementation optimization?

Only reference to 256 I could find is on this page that describes golang's runtime package: The runtime.MemStats struct has a couple of stat arrays of size 256:

type MemStats struct {
    PauseNs       [256]uint64 // circular buffer of recent GC pause durations, most recent at [(NumGC+255)%256]
    PauseEnd      [256]uint64 // circular buffer of recent GC pause end times

Here's example golang code I used:

func main() {
log.Printf("GOMAXPROCS %d
", runtime.GOMAXPROCS(-1))



P.S. Also, can someone point me to documentation on how this GOMAXPROCS relate to OS thread count used by golang scheduler (if at all). Shall we observe go-compiled code running GOMAXPROCS OS threads?

EDIT: Thanks @twotwotwo for pointing out how GOMAXPROCS relate to OS threads. Still it's interesting that documentation does not mention this 256 limit (other that in the MemStats struct which may or may not be related).

I wonder if anyone is aware of the true reason for this 256 number.

图片转代码服务由CSDN问答提供 功能建议

我正在MacBook和Ubuntu上使用golang 1.7.3,发现runtime.GOMAXPROCS限制为256。 有人知道这个限制来自哪里吗? 是否在任何地方都有记录,为什么会有限制? 这是实现优化吗?

在此页面上只能找到关于256的参考,该参考描述了golang的运行时软件包: 。 runtime.MemStats结构具有两个大小为256的状态数组:

  type MemStats结构{
 PauseNs [256] uint64 //循环缓冲区 最近的GC暂停持续时间,最近一次为[(NumGC + 255)%256] 
 PauseEnd [256] uint64 //最近的GC暂停结束时间的循环缓冲区


  func main(){
log.Printf(“ GOMAXPROCS%d 
”,运行时。  GOMAXPROCS(-1))



PS 此外,有人可以指出我有关此GOMAXPROCS与golang调度程序使用的OS线程计数的关系的文档(如果有的话)。 我们是否可以观察到运行GOMAXPROCS OS线程的经过编译的代码?

编辑:感谢@twotwotwo指出GOMAXPROCS与OS线程的关系。 仍然很有趣的是,文档中没有提到这个256的限制(其他在MemStats结构中可能或可能不相关的限制)。

我想知道是否有人知道这样做的真正原因 256个数字。

  • 写回答
  • 好问题 提建议
  • 关注问题
  • 收藏
  • 邀请回答

2条回答 默认 最新

  • dongyashun2559 2017-09-28 21:10

    Note that, starting the next Go 1.10 (Q1 2018), GOMAXPROCS will be limited by ... nothing.

    The runtime no longer artificially limits GOMAXPROCS (previously it was limited to 1024).

    See commit ee55000 by Austin Clements (aclements), which fixes issue 15131.

    Now that allp is dynamically allocated, there's no need for a hard cap on GOMAXPROCS.

    allp is defined here.

    See also commit e900e27:

    runtime: clean up loops over allp

    allp now has length gomaxprocs, which means none of allp[i] are nil or in state _Pdead.
    This lets replace several different styles of loops over allp with normal range loops.

    for i := 0; i < gomaxprocs; i++ { ... } loops can simply range over allp.
    Likewise, range loops over allp[:gomaxprocs] can just range over allp.

    Loops that check for p == nil || p.state == _Pdead don't need to check this any more.

    Loops that check for p == nil don't have to check this if dead Ps don't affect them. I checked that all such loops are, in fact, unaffected by dead Ps. One loop was potentially affected, which this fixes by zeroing p.gcAssistTime in procresize.

    解决 无用
    打赏 举报
  • douchou8935 2016-12-03 01:00

    The package runtime docs clarify how GOMAXPROCS relates to OS threads:

    The GOMAXPROCS variable limits the number of operating system threads that can execute user-level Go code simultaneously. There is no limit to the number of threads that can be blocked in system calls on behalf of Go code; those do not count against the GOMAXPROCS limit. This package's GOMAXPROCS function queries and changes the limit.

    So you could see more than GOMAXPROCS OS threads (because some are blocked in system calls, and there's no limit to how many), or fewer (because GOMAXPROCS is only documented to limit the number of threads, not prescribe it exactly).

    I think capping GOMAXPROCS is consistent with the spirit of that documentation--you specified you were OK with 1000 OS threads running Go code, but the runtime decided to 'only' run 256. That doesn't limit the number of goroutines active because they're multiplexed onto OS threads--when one goroutine blocks (waiting for a network read to complete, say) Go's internal scheduler starts other work on the same OS thread.

    The Go team might have made this choice to minimize the chance that Go programs end up running many times more OS threads than most machines today have cores; that would cause more OS context switches, which can be slower than user-mode goroutine switches that would occur if GOMAXPROCS were kept down to the number of CPU cores present. Or it might just have been convenient for the design Go's internal scheduler to have an upper bound on GOMAXPROCS.

    Goroutines vs Threads is not perfect, e.g. goroutines don't have segmented stacks now, but it may help you understand what's going on here under the hood.

    解决 无用
    打赏 举报

相关推荐 更多相似问题