84

何個のゴルーチンを無痛で使用できますか? たとえばウィキペディアによると、Erlang では、パフォーマンスを低下させることなく 2000 万のプロセスを作成できます。

更新:ゴルーチンのパフォーマンスを少し調査したところ、次のような結果が得られました。

  • ゴルーチンの寿命は sqrt() を 1000 回 (私にとっては ~45µs ) 計算するよりも長いようです。唯一の制限はメモリです
  • ゴルーチンのコストは 4 — 4.5 KB
4

7 に答える 7

79

ゴルーチンがブロックされている場合、以下以外にコストはかかりません。

  • メモリ使用量
  • 遅いガベージ コレクション

コスト (ゴルーチンの実行を実際に開始するためのメモリと平均時間に関して) は次のとおりです。

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

4 GB のメモリがインストールされているマシンでは、これによりゴルーチンの最大数が 100 万未満に制限されます。


ソース コード (上記の数値を既に理解している場合は、これを読む必要はありません):

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)
}
于 2011-12-16T13:16:47.397 に答える
6

それは、実行しているシステムに完全に依存します。しかし、ゴルーチンは非常に軽量です。平均的なプロセスでは、100.000 の同時ルーチンで問題が発生することはありません。もちろん、これがターゲット プラットフォームに当てはまるかどうかは、そのプラットフォームが何であるかを知らずに答えることはできません。

于 2011-12-14T19:01:09.453 に答える
5

言い換えれば、嘘、いまいましい嘘、ベンチマークがあります。Erlang ベンチマークの作成者が告白したように、

言うまでもなく、実際に何かを実行するのに十分なメモリがマシンに残っていませんでした。ストレステストアーラン

ハードウェアは何ですか?オペレーティング システムは何ですか?ベンチマーク ソース コードはどこにありますか? ベンチマークは何を測定し、証明/反証しようとしていますか?

于 2011-12-14T19:04:56.150 に答える
2

このトピックに関する Dave Cheney のすばらしい記事は次のとおりです

于 2014-04-28T17:08:21.833 に答える
0

ゴルーチンの数が問題になる場合は、プログラムで簡単に制限できます: mr51m0n/gorcこの例
を参照してください。

実行中のゴルーチンの数にしきい値を設定する

ゴルーチンを開始または停止するときにカウンターを増減できます。
実行中のゴルーチンの最小数または最大数を待機できるため、gorc同時に実行される管理されたゴルーチンの数のしきい値を設定できます。

于 2015-01-29T20:53:36.077 に答える