最大的门房数量 [英] Max number of goroutines

查看:79
本文介绍了最大的门房数量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我可以使用多少个非痛苦的无痛人流?例如维基百科说,在Erlang中可以创建2000万个进程而不会降低性能。 更新: 在goroutines的表现中进行了调查,得到了如下结果:




  • 看起来goroutine的生命周期更接近于计算sqrt()1000次(对我来说大约45μs),唯一的限制是内存
  • Goroutine花费4 - 4.5 KB


解决方案

如果goroutine被阻止,除了:


  • 内存使用情况

  • 更慢的垃圾收集功能



  • 成本(以内存和实际开始执行goroutine的平均时间为准):

      Go 1.6.2(2016年4月)
    32位x86 CPU(A10-7850K 4GHz)
    |套房数量:100000
    |每道菜:
    |内存:4536.84字节
    |时间:1.634248μs
    64位x86 CPU(A10-7850K 4GHz)
    |套房数量:100000
    |每道菜:
    |内存:4707.92字节
    |时间:1.842097μs

    Go release.r60.3(2011年12月)
    32位x86 CPU(1.6 GHz)
    |套房数量:100000
    |每道菜:
    |内存:4243.45字节
    |时间:5.815950μs

    在安装有4 GB内存的机器上,这限制了goroutine的最大数量(略低于100万)。






    源代码(如果您已经了解上面列出的数字,则无需阅读此代码) :

     包主

    导入(
    标记
    fmt
    os
    runtime
    time


    var n = flag.Int(n,1e5,Number )

    var ch = make(chan byte)
    var counter = 0

    func f(){
    counter ++
    < -ch //阻止这个goroutine
    }

    func main(){
    flag.Parse()
    if * n< = 0 {
    fmt.Fprintf(os.Stderr,goroutines无效数量)
    os.Exit(1)
    }

    //限制备用操作系统的数量线程为1
    runtime.GOMAXPROCS(1)

    //复制MemStats
    var m0 runtime.MemStats
    runtime.ReadMemStats(& m0)

    t0:= time.Now()。UnixNano()
    for i:= 0;我< * N; i ++ {
    go f()
    }
    runtime.Gosched()
    t1:= time.Now()。UnixNano()
    runtime.GC()

    //复制MemStats
    var m1 runtime.MemStats
    runtime.ReadMemStats(& m1)

    if counter!= * n {
    fmt.Fprintf(os.Stderr,未能开始执行所有goroutines)
    os.Exit(1)
    }

    fmt.Printf( goroutines的数量:%d \ n,* n)
    fmt.Printf(Per goroutine:\\\

    fmt.Printf(Memory:%.2f bytes\\\
    ,float64(m1.Sys-m0.Sys)/ float64(* n))
    fmt.Printf(Time:%fμs\\\
    ,float64(t1-t0)/ float64(* n)/ 1e3)
    }


    How many goroutines can I use painless? For example wikipedia says, in Erlang 20 million processes can be created without degrading performance.

    Update: I've just investigated in goroutines performance a little and got such a results:

    • It looks like goroutine lifetime is more then calculating sqrt() 1000 times ( ~45µs for me ), the only limitation is memory
    • Goroutine costs 4 — 4.5 KB

    解决方案

    If a goroutine is blocked, there is no cost involved other than:

    • memory usage
    • slower garbage-collection

    The costs (in terms of memory and average time to actually start executing a goroutine) are:

    Go 1.6.2 (April 2016)
      32-bit x86 CPU (A10-7850K 4GHz)
        | Number of goroutines: 100000
        | Per goroutine:
        |   Memory: 4536.84 bytes
        |   Time:   1.634248 µs
      64-bit x86 CPU (A10-7850K 4GHz)
        | Number of goroutines: 100000
        | Per goroutine:
        |   Memory: 4707.92 bytes
        |   Time:   1.842097 µs
    
    Go release.r60.3 (December 2011)
      32-bit x86 CPU (1.6 GHz)
        | Number of goroutines: 100000
        | Per goroutine:
        |   Memory: 4243.45 bytes
        |   Time:   5.815950 µs
    

    On a machine with 4 GB of memory installed, this limits the maximum number of goroutines to slightly less than 1 million.


    Source code (no need to read this if you already understand the numbers printed above):

    package main
    
    import (
        "flag"
        "fmt"
        "os"
        "runtime"
        "time"
    )
    
    var n = flag.Int("n", 1e5, "Number of goroutines to create")
    
    var ch = make(chan byte)
    var counter = 0
    
    func f() {
        counter++
        <-ch // Block this goroutine
    }
    
    func main() {
        flag.Parse()
        if *n <= 0 {
                fmt.Fprintf(os.Stderr, "invalid number of goroutines")
                os.Exit(1)
        }
    
        // Limit the number of spare OS threads to just 1
        runtime.GOMAXPROCS(1)
    
        // Make a copy of MemStats
        var m0 runtime.MemStats
        runtime.ReadMemStats(&m0)
    
        t0 := time.Now().UnixNano()
        for i := 0; i < *n; i++ {
                go f()
        }
        runtime.Gosched()
        t1 := time.Now().UnixNano()
        runtime.GC()
    
        // Make a copy of MemStats
        var m1 runtime.MemStats
        runtime.ReadMemStats(&m1)
    
        if counter != *n {
                fmt.Fprintf(os.Stderr, "failed to begin execution of all goroutines")
                os.Exit(1)
        }
    
        fmt.Printf("Number of goroutines: %d\n", *n)
        fmt.Printf("Per goroutine:\n")
        fmt.Printf("  Memory: %.2f bytes\n", float64(m1.Sys-m0.Sys)/float64(*n))
        fmt.Printf("  Time:   %f µs\n", float64(t1-t0)/float64(*n)/1e3)
    }
    

    这篇关于最大的门房数量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆