、3- 、あなたがlock sync.RWMutex
を使用せずに、CPUコアごとにタスクを分割してもよい:
+30x
チャネルを使用して最適化とruntime.NumCPU()
を、これはあなたのサンプルコードながら、2ms
2のコアと993µs
8上のコアを取ります2つのコアと40ms
8のコアに61ms
を取ります
このワーキングサンプルコードと出力を参照してください。
package main
import (
"fmt"
"math"
"runtime"
"time"
)
func main() {
nCPU := runtime.NumCPU()
fmt.Println("nCPU =", nCPU)
ch := make(chan float64, nCPU)
startTime := time.Now()
a := 0.0
b := 1.0
n := 100000.0
deltax := (b - a)/n
stepPerCPU := n/float64(nCPU)
for start := 0.0; start < n; {
stop := start + stepPerCPU
go f(start, stop, a, deltax, ch)
start = stop
}
integral := 0.0
for i := 0; i < nCPU; i++ {
integral += <-ch
}
fmt.Println(time.Now().Sub(startTime))
fmt.Println(deltax * integral)
}
func f(start, stop, a, deltax float64, ch chan float64) {
result := 0.0
for i := start; i < stop; i++ {
result += math.Sqrt(a + deltax*(i+0.5))
}
ch <- result
}
2つのコアの出力:8つのコアの
nCPU = 2
2.0001ms
0.6666666685900485
出力:
nCPU = 8
993µs
0.6666666685900456
あなたのサンプルコード、2つのコアの出力:
0.6666666685900424
61.0035ms
8上のあなたのサンプルコード、出力コア:
0.6666666685900415
40.9964ms
0あなたはここに2個のコア、これは2つのコアで
110ms
がかかりますが、これと同じCPU上 1を使用してを使用して見るように
:良いベンチマークの統計情報については
2 - は、多数のサンプル(ビッグN)を使用します
package main
import (
"fmt"
"math"
"time"
)
func main() {
now := time.Now()
a := 0.0
b := 1.0
n := 10000000.0
deltax := (b - a)/n
result := 0.0
for i := 0.0; i < n; i++ {
result += math.Sqrt(a + deltax*(i+0.5))
}
fmt.Println(time.Now().Sub(now))
fmt.Println(deltax * result)
}
01:n := 10000000.0
とシングルゴルーチンで 、このワーキングサンプルコードを参照してください:コアこれは215ms
n := 10000000.0
となります
出力:n := 10000000.0
と2ゴルーチンで
215.0123ms
0.6666666666685884
、このワーキングサンプルコードを参照してください。
package main
import (
"fmt"
"math"
"runtime"
"time"
)
func main() {
nCPU := runtime.NumCPU()
fmt.Println("nCPU =", nCPU)
ch := make(chan float64, nCPU)
startTime := time.Now()
a := 0.0
b := 1.0
n := 10000000.0
deltax := (b - a)/n
stepPerCPU := n/float64(nCPU)
for start := 0.0; start < n; {
stop := start + stepPerCPU
go f(start, stop, a, deltax, ch)
start = stop
}
integral := 0.0
for i := 0; i < nCPU; i++ {
integral += <-ch
}
fmt.Println(time.Now().Sub(startTime))
fmt.Println(deltax * integral)
}
func f(start, stop, a, deltax float64, ch chan float64) {
result := 0.0
for i := start; i < stop; i++ {
result += math.Sqrt(a + deltax*(i+0.5))
}
ch <- result
}
出力:
nCPU = 2
110.0063ms
0.6666666666686073
の1- ありゴルーチンの数の最適なポイントであり、この時点からゴルーチンの増加数は、プログラムの実行時間を短縮しません:2つのコアのCPUで
、次のコードを使用して、結果は次のとおりです。
nCPU: 1, 2, 4, 8, 16
Time: 2.16s, 1.1220642s, 1.1060633s, 1.1140637s, 1.1380651s
あなたはnCPU=1
時間nCPU=2
から見たような減少は十分な大きさであるが、この時点の後に、それはそうnCPU := runtime.NumCPU()
が、ここで十分です使用して、そのnCPU=2
2コアCPU上で、このサンプル・コードの最適点があり、あまりないです。
package main
import (
"fmt"
"math"
"time"
)
func main() {
nCPU := 2 //[email protected] [email protected] [email protected] [email protected] [email protected]
fmt.Println("nCPU =", nCPU)
ch := make(chan float64, nCPU)
startTime := time.Now()
a := 0.0
b := 1.0
n := 100000000.0
deltax := (b - a)/n
stepPerCPU := n/float64(nCPU)
for start := 0.0; start < n; {
stop := start + stepPerCPU
go f(start, stop, a, deltax, ch)
start = stop
}
integral := 0.0
for i := 0; i < nCPU; i++ {
integral += <-ch
}
fmt.Println(time.Now().Sub(startTime))
fmt.Println(deltax * integral)
}
func f(start, stop, a, deltax float64, ch chan float64) {
result := 0.0
for i := start; i < stop; i++ {
result += math.Sqrt(a + deltax*(i+0.5))
}
ch <- result
}
@ husain-al-marzooq私はこれが役立つことを望みます。 –