私はgoパッケージ「ランタイム」について読んでいて、とりわけ(func GOMAXPROCS(n int))プログラムの実行に使用できるCPUユニットの数を設定できることを確認しています。選択した特定の CPU でゴルーチンを強制的に実行できますか?
2 に答える
現代の Go では、効率のためにゴルーチンをスレッドにロックしません。Go 1.5では、ゴルーチンが OS スレッド間で切り替わる頻度を最小限に抑えるために、ゴルーチン スケジューリング アフィニティが追加されました。また、CPU 間の残りの移行のコストは、カーネル モードへのコンテキスト スイッチを回避するユーザー モード スケジューラの利点と比較検討する必要があります。最後に、スイッチング コストが実際の問題である場合、個々の作業項目ではなく作業のバッチを通信するなどして、切り替えの必要性を減らすために、プログラム ロジックを変更することに重点を置いたほうがよい場合があります。
しかし、これらすべてを考慮しても、C API でゴルーチンが必要な場合のように、ゴルーチンをロックする必要がある場合があります。以下ではその場合を想定します。
プログラム全体が で実行される場合GOMAXPROCS=1
、schedutils パッケージからタスクセット ユーティリティを呼び出して CPU アフィニティを設定するのは比較的簡単です。
ゴルーチンは実行時に OS スレッド間で移行GOMAXPROCS > 1
されるため、運が悪いと思っていました。実際、James Henstridgeは、ゴルーチンの移行を防ぐために使用できると指摘しています 。ただし、ゴルーチンをロックした後、現在のスレッドの CPU アフィニティを設定する Go stdlib 関数については知りません。どうやらGo は cgo モードで pthread を使用するため、cgo と call を使用できる可能性があります。システムコールの話なので、詳細はOSによって異なります。runtime.LockOSThread()
pthread_setaffinity_np
(プログラム全体が純粋な Go (C がリンクされていない) である場合、モジュールを介してsched_setaffinity
ゼロのpid
パラメーターで呼び出すことができる場合がありsyscall
ます。しかし、それは注意が必要です。)