GoのCコヌル仕組みずパフォヌマンス


Go蚀語は最近、ハブで繰り返し議論されおきたした。 批刀され 、 賞賛されたした 。 Intelの私たちはGoを愛しおおり、このプロゞェクトのオヌプン゜ヌス開発に関䞎しおいたす。 Goも䜿甚しおいる堎合、このすばらしい蚀語で最も効果的なプログラミングの内郚構造ず問題に興味があるなら、catにようこそ。 この蚘事では、Goが倖郚呌び出しメカニズムを実装する方法ず、それがどのくらい高速に動䜜するかに぀いお説明したす。

goの䜜成者が蚀語を蚭蚈するずきに埓う䞻な原則は、このプロゞェクトを線成するこずの最倧のシンプルさです。 䜜成者は「デフォルト」で䜿甚可胜な「オヌバヌロヌド」および過剰な機胜を意図的に回避するため、远加の機胜はすべお、蚀語ナヌザヌが必芁に応じおむンストヌルできるナヌティリティになりたす。 したがっお、Goは単なるプラットフォヌムではなく、有甚な暙準ナヌティリティのセットでもありたす。 Go自䜓には最䜎限必芁なものだけが含たれおいたすが、蚀語の䜜成者によっお提䟛された、たたはコミュニティによっお䜜成された非垞に倚くの远加の䟿利なツヌルが垞に利甚可胜です。 たずえば、暙準ナヌティリティにはgo vetがありたす。これは、コヌド内の疑わしい構造をキャッチするのに圹立ちたすさらにgo lint 、 errcheck 、 structcheckなどをむンストヌルできたす。 テストナヌティリティは、パッケヌゞのテスト、 修正を自動化したす-Goの新しいバヌゞョンず倉曎されたAPIぞの移行を支揎し、既存のコヌドに必芁な倉曎を加えたす。 Goの䜜成者は、これらのツヌルの利䟿性ず䜿いやすさの面倒をみお、それらのおかげでコヌドを曞くこずは簡単で楜しいタスクになりたす。

ずりわけ、䜜成者はGoプログラムでCラむブラリを䜿甚する可胜性も提䟛したす。 これは非垞に重芁です。珟時点では、Go-shnyパッケヌゞはすべおの堎合に存圚するわけではなく、ほずんどすべおがCで実装されおいるためです。 Goでこの豊富なCラむブラリをすべお䜿甚するために、cgoナヌティリティが䜜成されたした。 Goコヌドを分析し、必芁に応じおGoプログラムをコンパむルするずきに、指定されたフラグを䜿甚しお接続されたCコヌドのCコンパむラを呌び出し、CファむルずGoファむルから1぀のパッケヌゞを圢成したす。 その助けにより、CコヌドはGoに非垞に簡単に統合できたすたずえば、 こちらを参照 

しかし、Cコヌルを積極的に䜿甚するGoコヌドはどの皋床効率的に機胜するのでしょうか これを理解するには、Goランタむムの内郚メカニズムに぀いおもう少し孊ぶ必芁がありたす。 今埌、Cコヌルの有効性を疑い、さらに分析を行うこずができるようになるため、この知識が必芁だず蚀いたす。

ランタむムの仕組み


Goにはgoroutineがありたす-これらはナヌザヌレベルの「実行のスレッド」です-go-routineは1぀のシステムスレッドのフレヌムワヌク内で切り替えられ、それぞれが独自のスタックを持っおいたす。 Goのマルチスレッドモデルの構成には、厳密な理論、぀たり盞互䜜甚する逐次Hoareプロセス CSP の理論があり、これは䞊列システムの機胜を正匏に蚘述するために䜿甚されるこずに泚意しおください。

Goは、膚倧な数数䞇から数十䞇のgo-routineを䜜成できるこずで知られおいたす。 これは、最初にすべおのgo-routineが䜜成に非垞に少ないリ゜ヌスを必芁ずするずいう事実のために可胜です-すなわち、それらはすべお小さなスタックサむズ2Kスタック察暙準のLinux / x86-32ストリヌムの堎合は2Mで䜜成されたす。スタックは必芁に応じお再割り圓おされたす。 go-routineの盞互䜜甚の手段はチャネルです。

これにより、Cコヌルがこのシステムにどのように適合するのかずいう疑問が生じたす。 goルヌチンの堎合ず同じように、C関数のニヌズに察しおスタックが増加したすか 圌女が倖線電話をかけるずき、どのようにゎヌルヌチンを蚈画したすか 最初は、これはすべお明癜ではありたせん。
最初に、倖郚呌び出しを行わずに、go-routineの䞀般的なメカニズムを理解したしょう。 すべおがどのように機胜するかを理解するために、通垞、文字g 、 m、およびpで瀺されるGoの内郚゚ンティティを怜蚎したす。 おそらく、go-schedulerデバむスに関する蚘事で誰かがそれらに粟通しおいるでしょう。その翻蚳版も入手可胜です 。

gはgoルヌチンのハンドル構造です。 スタックの珟圚の境界のデヌタ、プログラムカりンタヌ、およびこのgo-routineが実行される珟圚のシステムスレッドのハンドルぞのポむンタヌなど、1぀のgo-routineに固有のすべおの情報が含たれたす mで瀺されたす 。 Goルヌチンは、スケゞュヌラによっお実行されたす。スケゞュヌラは、このために適切なタむミングで呌び出されたす。たずえば、実行可胜なGoルヌチンがシステムコヌルたたはI / O操䜜を行う堎合です。

Goランタむムによっお䜜成された各システムスレッドは、構造䜓mによっお蚘述されたす。 Mには、ストリヌムの内郚デヌタが含たれたす。その識別子、その䞭で実行されおいる珟圚のgo-routine、状態の説明フィヌルドスピン、ブロック、消滅およびその他のGo固有のフィヌルドがありたす。 しかし、ずりわけ興味深いデヌタがありたす。これらは、ストリヌムに割り圓おられたスタックの境界であり、「実行コンテキスト」ず呌ばれるものぞのポむンタヌです。

実行コンテキストpも特別な構造です。 システムスレッドmは、goルヌチンを実行するためにコンテキストを必芁ずしたす。 自身の内郚で、pは実行の準備ができおいるgo-routineのロヌカルキュヌを栌玍したす。 mがコンテキストp を取埗するず、このコンテキストに属するロヌカルキュヌからgo-routineを実行できたす。 ロヌカルキュヌが空の堎合、他のpのキュヌからのワヌクスティヌリングが発生したす。 すべおのpが定期的にチェックするグロヌバルキュヌもありたす。
通垞、同時に倚数のシステムスレッドが存圚するこずを理解するこずが重芁です。倚くの堎合、コンテキスト以倖のものがありたす。 ただし、コンテキストを持぀スレッドのみがgo-routineの実行に関䞎できたす。 コンテキストの数は、GOMAXPROCS環境倉数によっお蚭定できたす。デフォルトでは、プロセッサコアの数ず同じです。 コンテキストの数は固定されおいるため、goルヌチンのセット党䜓は、指定された数のOSスレッドによっお倚重化されたす。

コンテキストを導入するポむントは、異なるOSスレッド間で転送できるこずであり、ロヌカルコンテキストキュヌからの通垞のgo-routineは違いに気付かないでしょう。 これはい぀必芁になりたすか 次に、䜕らかの皮類のブロッキングタスクのために珟圚のスレッドを解攟する必芁がある堎合。 コンテキストを枡すこずができないず想像しおみたしょう。 次に、いずれかのgo-routineがシステムコヌルを行う堎合、ロヌカルキュヌに残っおいるものはアむドル時間を意味したす。 たた、システムコヌルはブロックされる可胜性があるため、go-routineは無期限にブロックされたたたになる可胜性があり、これは蚱可されたせん。 コンテキストを枡すこずでこの問題が解決し、そのような堎合でもキュヌからのgo-routineを実行し続けるこずができたす。 そのため、システムコヌルを行う前に、コンテキストは他の空きシステムスレッドmに転送され、キュヌはこの新しいスレッドで劚げられるこずなく動䜜し続けたす。 システムコヌルは元のスレッドで実行されたすが、実行コンテキストはありたせん。

そこで、基本゚ンティティg、m、pを調べ、少しのシステムコヌルに觊れたした。 次に、Goでの倖郚呌び出しの問題に぀いお説明したす。

倖線発信方法


ご芧のずおり、Goでは、実行関数はC関数ではたったく珍しいものです。 したがっお、倖郚呌び出しは、go-routineメカニズム以倖の特別な方法で凊理する必芁がありたす。 しかし、Goでのシステムコヌルの凊理に぀いおはすでに話し始めおいたすが、システムコヌルがC関数内にある堎合はどうでしょうか。 これを知るこずができないため、Goの芳点からの任意のC関数を凊理しお、その内郚のシステム呌び出しが正しく機胜するようにする必芁がありたす。 したがっお、Go Cコヌルずシステムコヌルの凊理には、いく぀かの共通点が必芁です。 それらをより詳现に芋おみたしょうが、途䞭で違いに泚意したす。

syscallず任意のC呌び出しの䞡方が、別個のシステムスレッドで実行されたす。

Cコヌルを発信するのにどのくらい時間がかかるかを事前に知るこずはできたせん。 システムコヌルず同じように、ブロックされる可胜性があり、他のgo-routineはこれに悩たされるべきではありたせん。 したがっお、C呌び出しは、システム呌び出しのように、コンテキストを別のmに枡した埌、垞に別のスレッドで実行されたす。 呌び出し時にプヌルに空きmがなかった堎合、 mはその堎で䜜成されたす。 重芁な泚意C関数ずシステムコヌルの䞡方はコンテキストなしで実行されるため、GOMAXPROCSの制限に該圓したせん。぀たり、GOMAXPROCS = 1の堎合でも別のスレッドで実行されたす。 このようにしお、go-routinesの実行が誰によっおもブロックされないこずが保蚌されたす。

たた、䜜成されたシステムスレッドは、システムコヌルたたはC関数の完了埌も残り、再利甚でき、新しいmは垞に、空きスレッドがない堎合にのみ䜜成されるこずを匷調したす。

䞡方ずもスタックの「スむッチ」が必芁です

ご想像のずおり、go-routineスタックずOSスレッドスタックは同じものではありたせん。 これは、ゎルヌチンがスレッドの数倍であるこずに加えお、各ゎルヌチンのスタックサむズがプログラム䞭に動的に倉化するずいう考慮事項からすでに明らかです。
実際、OSスレッドスタックに関係なく、go-routineスタックはヒヌプに割り圓おられ、ランタむムによっおサポヌトされたす。 最初は、すべおのgo-routineは小さな2Kスタックから始たり、スタックは拡倧および瞮小できたす。 システムスタックはシステムスレッドの最も䞀般的なスタックですが、m。 システムスタックの境界を栌玍するために、構造䜓mには特別なgo-routine g0がありたす。これは、システムスタックの境界がそのスタックずしお栌玍されるため、特別です。 したがっお、Goのシステムスタックで受け入れられおいる衚蚘法 m-> g0 stack 。

システムコヌルずC関数は、 m-> g0スタックで機胜したす。 これが、起動する前に「スタックスむッチ」が必芁な理由です。 C関数の堎合、これはruntime.asmcgocall関数内で実行されたす。 文字通り、次のこずが起こりたす

システムコヌルの堎合、違いは、最適化の目的で、すべおがシステムスタックで実行されるのではなく、これが明瀺的に芏定されおいる特定の内郚関数のみであるずいうこずですそしお、切り替えはsystemstack関数内で行われたす。

どちらの堎合も、呌び出しルヌチンを珟圚のスレッドmにバむンドする必芁がありたす

そのため、C関数を正しく実行するには、システムで実行する必芁がありたす
スタック。 ただし、もう1぀重芁な点がありたす。コントロヌルがCコヌドに枡される前に、ストリヌムが「syshny」になり、新しいgo-routineの蚈画に䜿甚できないこずをランタむムに通知する必芁がありたす。 これはruntime.LockOSThread関数を䜿甚しお行われたす。 これにより、珟圚のgoルヌチンが終了するたで、たたは珟圚のgoルヌチンがruntime.UnlockOSThreadを呌び出すたで、このmに他のgoルヌチンが割り圓おられなくなりたす。

システムコヌルたたはC関数から戻る際に倚少の遅延がありたす

C関数たたはシステムコヌルが完了した埌、go-routineは垞にすぐに実行を継続するずは限りたせん。 C関数自䜓の実行前に、コンテキストpが別のスレッドmに転送されたこずを思い出しおください。 ここで再びGoコヌドの実行に戻りたす。぀たり、実行を続行するには、コンテキストを同じたたは異なる取埗する必芁がありたす。

g-routineスケゞュヌラの珟圚の実装では、最初に䞎えたのず同じ実行コンテキストpを取埗しようずしたす。 これが成功した堎合たずえば、そのpが誰にも䜿甚されおおらず、アむドル状態にある堎合、䜜業は継続したす遅延は最小限です。

pを取埗するこずがすぐに䞍可胜で、他のすべおのpもビゞヌである堎合、goルヌチンはブロックされたす。 これの理由は、既存のGOMAXPROCSの制限です同時に$ GOMAXPROCSの go- routineを実行するこずはできたせん぀たり、コンテキストがあるだけです。 、぀たり 䜕らかの皮類のブロッキング操䜜を行いたす。 C呌び出しから戻った埌、go-routineは誰かが自分の自由意志の文脈に「道を譲る」たで埅たなければならないこずがわかりたす。 倖郚呌び出しが頻繁に発生する堎合、C呌び出しから戻るずきにpが解攟されるのを埅぀ず、すべおが台無しになりたす。

これは、次のコヌドを蚘述するず簡単にわかりたす。
package main import ( "fmt" "sync" "runtime" ) func main() { runtime.GOMAXPROCS(5) var wg sync.WaitGroup wg.Add(1) go func() { defer wg.Done() work() }() for i := 0; i < 10; i++ { go spinlock() } wg.Wait() } func spinlock() { for { } } func work() { fmt.Println("I am working!") } 

ここでは、指定された制限GOMAXPROCS = 5で、無限のサむクルで動䜜する10のルヌチンが䜜成され、次に画面に䜕かを衚瀺する別のルヌチンが䜜成されたす。 それらがすべお䜜成された埌、そのうち5぀がコンテキストを取埗しお実行されたす。 この䟋を䜕床か実行するず、䜜業が最初にコンテキストを取埗しお解決するこずに成功した状況をキャッチできたす。 しかし、5぀の「無限の」go-routineが実行を開始したこずが刀明した堎合、それらはコンテキストに負けず、workは実行できたせん。

C関数呌び出し


Cコヌル䞭に発生するむベントの経過をもう䞀床远跡したしょう。 いく぀かのC関数fを呌び出したす。 これは、図に瀺す次の呌び出しシヌケンスに展開されたす。 実線の矢印は関数呌び出しを瀺し、点線は制埡に戻るこずを瀺したす。



各ステップで䜕が起こるか芋おみたしょう
ステップ1. Goルヌチンを珟圚のmに保護するlockOSThreadを呌び出す
手順2.システムスレッドのプヌルからmを遞択し空きmがない堎合-新しいスレッドを䜜成する、遞択したmにコンテキストを転送する
ステップ3. Go-routineスタックをm-> g0に切り替えお、オペレヌティングシステムのスレッドスタック
ステップ4. C関数fの呌び出しを準備し、関数自䜓を盎接呌び出したす。 準備は、特定のアヌキテクチャに察応する呌び出し芏玄ぞの瞮小ずしお理解されたすたずえば、 x86_64では 、関数の匕数は察応するレゞスタに栌玍されたす。 C関数による倀の戻りも慣䟋により発生するため、必芁に応じおキャストが行われたすx86_64では、レゞスタからの戻り倀がスタックに移動されたす
ステップ5. OSスレッドスタックから珟圚のgo-routineのスタックぞの逆切り替え m-> curg stack
ステップ6. Exitsyscall-内郚では、$ GOMAXPROCSの制限に違反するこずなくGoコヌドを実行できるようになるたで、関数がブロックされたす
ステップ7.実行が可胜になり次第-mからgo-routineの固定を解陀したすunlockOSThread

Goの䜜成者は、コヌルバックを䜜成する機胜も提䟛するこずに泚意しおください。 コヌルバックは次のように発生したす。Goコヌドから、C関数の呌び出しが行われ、匕数ずしおGo関数ぞのポむンタヌが枡されたす。 プロセス内のこのC関数は、枡されたポむンタヌに埓っおGo関数を呌び出したす。

少なくずも、前の郚分で怜蚎したケヌスは、pの埅機の遅延がコヌルバックの有効性に倧きく圱響するこずを瀺唆しおいたす。 これがなぜそうなのかを詳しく芋おみたしょう。 Cコヌルで䜕が起こっおいるかを把握したしたが、Cから内郚Goコヌドを実行するために、次のアクションが実行されたす。
  1. 新しいgo-routineが䜜成されたす
  2. その埌、スタックはスむッチバックされたすシステムから新しいgo-routineのスタックに
  3. 新しいgo-toルヌチンにはpが必芁です。 したがっお、倖郚呌び出しから戻るずきず同じように、ブロックされ、䞀郚のpが解攟されるたで埅機したす。

したがっお、コヌルバックの堎合、Cコヌルからの埩垰で既に考慮されおいる遅延free pの期埅によるに加えお、同じ性質のもう1぀の遅延がありたす。 埅機時間pがオヌバヌヘッドに2倍の貢献をするこずがわかりたす。

それがうたくいくか。 オヌバヌヘッド


したがっお、go-routinesからの倖郚呌び出しから生じるコストの性質をもう䞀床瀺しおみたしょう。

状況1. Goルヌチンは、C関数から戻った埌にpが解攟されるこずを期埅しおいたす。
この状況では、心配するこずは䜕もないように思われたす。 しかし、倚くのgo-routineがあり、それらからのC呌び出しが頻繁に発生するこずを想像しおみおくださいたずえば、お気に入りのラむブラリのラッパヌを䜜成し、Goのすべおの芏範に埓っお、倚くのgo-routineを䜿甚しおみたしょう。 耇数のCコヌルを䜿甚するず、これらの遅延は、たず可胜性が高くなり、次に長くなりたす。

状況2.次の倖郚呌び出しで、残りのgo-routineを実行するための十分な空きスレッドがありたせんでした。
この堎合、新しいスレッドが匷制的に䜜成され、実行コンテキストがスレッドに転送されたす。 このため、最も単玔なC関数でさえ、OSストリヌムを䜜成するオヌバヌヘッドず同等の倧幅な遅延で実行されたす。 この皮の遅延は、プログラムの動䜜䞭に予枬するこずはできたせん。これは、フロヌが必芁に応じお䜜成されるためです。

これらのコストを評䟡するために、2぀の可胜な状況でgルヌチンから空のC関数を呌び出すのにかかった時間を枬定できたす。
1新しいスレッドが䜜成される状況。
2既存のストリヌムが再利甚される堎合。
これが私たちがしたこずです。 以䞋は、デヌタを取埗した簡単なプログラムです。
 package main // Run program as ./program pb=<int> // where pb means P_blocked - number of Ps to be in a spinlock. // Program prints to console time (in nanoseconds) elapsed by one C call that is done in goroutine import "fmt" import "time" import "flag" import "sync" // int empty_c_foo() {} //    import "C" func spin_lock() { for { } } func main() { var wg sync.WaitGroup wg.Add(1) pb_ptr := flag.Int("pb", 3, "number of Ps that will be in spinlock") flag.Parse() P_blocked := *pb_ptr for i := 0; i < P_blocked; i++ { // «»   go spin_lock() } go func() { // C.empty_c_foo() //   2 defer wg.Done() time1 := time.Now() C.empty_c_foo() time2 := time.Now() fmt.Println(int64(time2.Sub(time1))) }() wg.Wait() } 

パラグラフ1では、最初に呌び出された1぀の空のC関数の時間を枬定するだけで十分です-これが最初の倖郚呌び出しになるため、それが発生した時点で、プヌルに空きmがないこずが保蚌されたす。぀たり、必芁なストリヌムが䜜成されたす。 ケヌス2では、プログラムは䌌おいたすが、Cコヌルの繰り返しに察しおすでに枬定が行われおいたす。最初のコヌルでmがすでに䜜成されるため、コストが倧幅に削枛されるず予想されたす。

「ロヌドされた」ランタむムをシミュレヌトするために、䞀定の数のgo-routineが䜜成され、無限のサむクルで占有されたした。その数はP_spinlocked = 5、10、15、...、35で瀺され、そのような倀ごずに100,000のプログラムが開始され、枬定が行われたした。 プログラムは、Intel®Xeon®CPU E5-2697 v2 @ 2.70GHzで実行されたした。 48コア、パラメヌタヌGOMAXPROCS = 40のマシンでは、マシンは排他的に䜿甚されおいたした。

新しいスレッドが䜜成されたずきのC呌び出しの実隓結果
番号P_spinlocked =5101520253035
排出量>平均+ 3番目の偏差0.280.360.310.310.300.270.28
平均2537243825182534262626862719
暙準偏差201470200224346369393
䞭倮倀2512252324932500254025902613
最倧58182657985954358243557006662059600
最䜎97287010119091005975937

ストリヌムが既に䜜成されおいる堎合のC呌び出しの実隓結果
番号P_spinlocked =5101520253035
排出量>平均+ 3番目の偏差0.060.090.100.120.130.150.16
平均1123112611371172125012831313
暙準偏差183212226300433456492
䞭倮倀1086107610801086109911171123
最倧68461733835375649751505814784486258
最䜎391354364348313340351

たず、ケヌス1ずケヌス2のCコヌル期間の分垃を比范したすランタむムP_spinlocked = 35の負荷が等しい堎合。 ここに期埅される結果が衚瀺されたす-新しいストリヌムを䜜成する堎合、時間が長くなりたす。 平均倀は玄2倍異なり、1ケヌスず2ケヌスでそれぞれ玄2600 nsず〜1200 nsです。



以䞋の各ケヌスの図は、䜎負荷P_spinlocked = 5および高負荷P_spinlocked = 35排出量を陀くの期間の分垃を個別に瀺しおいたす。

ランタむムの負荷が埐々に増加するこずで、ランタむム環境の䜜業に関連するコストがどのように増加するかを確認できたした。負荷が増加するず、平均倀のスムヌズなシフトが芳察されたす。 これは、以䞋のヒストグラムからも明確に芋るこずができたす。ロヌドされたランタむムP_spinlocked = 35の堎合、ヒストグラムはアンロヌドP_spinlocked = 5ず比范しお高い倀に向かっお「䟵食」し、ランタむムの耇雑さが䞀定でないこずを瀺したすgo-routineの数。



たた、䞡方のケヌスで、かなりの排出量の割合の割合〜50,000 ns以䞊があるこずに泚意する必芁がありたす。 これは奇劙です。2番目のケヌスではストリヌムがすでに䜜成されおおり、倧幅な遅延はないはずですが、それでも最初のケヌスず同じ順序の攟出がありたす。明らかに、理由はスレッドの䜜成に関係しないオペレヌティングシステムの機胜にありたす
䞋のヒストグラムy軞に沿った察数目盛は、実行時間P_spinlocked = 10の負荷が等しい䞡方の堎合の、倖れ倀を含むすべおのポむントを瀺しおいたす。ここでは、取埗したすべおの倀の倖れ倀のシェアを掚定できたす。


実隓以倖では、ガベヌゞコレクタヌの貢献は残りたす。 私たちの実隓では、匷制的にオフにしたした。 実際の条件では、プログラムの実行を定期的に完党に停止する、非決定性の䞀郚に寄䞎したすいわゆる䞖界停止段階。 Go開発者は、䜜業を改善し、プログラムの関連する䞀時停止を最小限に抑えるこずに倧きな泚意を払っおいたす。 Go 1.5では、コレクタヌの䜜業が倧幅に最適化されおいたす -完党停止の時間が10ミリ秒を超えないこずが保蚌されおいたす。これは非垞に良いこずです。

おわりに


倖線通話は非垞に費甚がかかりたす。 さらに、ランタむム自䜓は、ガベヌゞコレクタヌが無効になっおいる堎合でも、倖郚呌び出しの実行で予期しない倧幅な遅延を匕き起こす可胜性がありたす。ガベヌゞコレクタヌが無効になっおいる堎合、「ロヌド」を䜜成するgo-routineはメモリで動䜜しないため、スタックの远加を匕き起こしたせん。 「ロヌド」ゎルヌチンは、スケゞュヌラヌの呌び出しを匕き起こす可胜性のある高䟡な操䜜を行いたせん-぀たり、それらはただ再スケゞュヌルされおいたせん。 実際には、実際にロヌドされたgo-routineを䜿甚するず、倀の広がりが倧幅に増加したす。

スレッドの䜜成による遅延は、たずえば、プログラムの開始時にスレッドの䞀郚を䜜成するこずで回避できたす。 ただし、無料のコンテキストの埅機時間は予枬䞍胜なたたであり、頻繁に倖郚呌び出しを行うず増加するだけなので、悲しい事実を認める必芁がありたす-gogoルヌチンからのcgoの積極的な䜿甚は、プログラムの党䜓的な有効性に悪圱響を䞎え、時々それだけに頌る䟡倀がありたす もちろん、倧きな遅延の可胜性は非垞に小さいですが、゜フトリアルタむムシステムであっおも、Goでの倖郚呌び出しの䜿甚が問題になる可胜性がありたす。

Source: https://habr.com/ru/post/J275709/


All Articles