だから、私は並行しているコードを持っており、それは各CPU /コア上で実行されることを意図しています。golangで使用されている複数のコアを防止する方法を検出するにはどうすればよいですか?
入力/出力値を有する2つの大きなベクトル
var (
input = make([]float64, rowCount)
output = make([]float64, rowCount)
)
は、これらが充填され、Iは各入出力ペアの間の距離(誤差)を計算したいがあります。
var d float64 // Error to be computed
// Setup a worker "for each CPU"
ch := make(chan float64)
nw := runtime.NumCPU()
for w := 0; w < nw; w++ {
go func(id int) {
var wd float64
// eg nw = 4
// worker0, i = 0, 4, 8, 12...
// worker1, i = 1, 5, 9, 13...
// worker2, i = 2, 6, 10, 14...
// worker3, i = 3, 7, 11, 15...
for i := id; i < rowCount; i += nw {
res := compute(input[i])
wd += distance(res, output[i])
}
ch <- wd
}(w)
}
// Compute total distance
for w := 0; w < nw; w++ {
d += <-ch
}
アイデアは、各CPU /コアのための単一の労働者を持つことであり、各労働者が行のサブセットを処理します。ペアが独立している、可能な同時バージョンは次のようです。
私が抱えている問題は、このコードがシリアルコードより高速ではないということです。
ここでは、runtime.GOMAXPROCS
はすでにruntime.NumCPU()
に設定されていますので、Go 1.7を使用していますが、明示的に設定してもパフォーマンスは向上しません。
- 距離はちょうど
(a-b)*(a-b)
です。 - 計算はもう少し複雑ですが、再入可能でグローバルデータを使用してください。(
math.Pow
とmath.Sqrt
関数を使用しています)。 - 他のゴルーチンが実行されていません。だから、
、読書のためのグローバルデータ(入力/出力)にアクセスする以外にも、私は(例えば、math/rand
を使用していない)を認識していはロック/ミューテックスはありません。
-race
とコンパイルされていて、何も出現しませんでした。
私のホストには4つの仮想コアがありますが、このコードを実行すると(htopを使用して)CPU使用率は102%になりますが、過去にはすべてを使用する他のgoコードコア。
私は調査したいと思いますが、ランタイムがスレッドを割り当ててどのようにゴルーチンをスケジュールするのか分かりません。
このような問題をどのようにデバッグできますか?この場合、pprof
は私を助けますか? runtime
パッケージはどうですか?
実際には、 'ch'チャンネルの後ろに1つの隠れたミューテックスがあります。 – nvartolomei
はい、ありがとう!しかし、ミューテックスは、処理されるデータと比較して通常は低い数である「nw」時間だけ使用され、チャネルは計算プロセス全体で非常に遅く使用される。それが問題なのかどうかはわかりませんが、たとえそれがあったとしても、私の疑問は残っています。私のコードがCPUをそれ以上使用していないというミューテックスが原因であることはどうしてわかりますか? – AkiRoss
あなたは正しいです。私はちょうどあなたのものに似たサンプルを試しました、そして、それはすべての利用可能なコアを使います。私は完全なコードの例がより有用であると思います。 – nvartolomei