私は最近、友人の推薦で学習を始めました。これまでのところ、私はそれを愛していますが、私は軽い同時並行性のパワーの完璧な例を書いていました(私は思ったように)、驚くべき結果を得ました...私は間違ったことをしていると思われます。高価なgoroutinesがいかに誤解しているか。私はここにいるいくつかのgophersが洞察力を提供することを望んでいます。同時実行:Chudnovkyのアルゴリズム、同期よりも遅い
私はgoroutinesと単純な同期実行の両方を使ってGoでChudnovskyのアルゴリズムを書いた。私は、それぞれの計算が他の計算と独立していると仮定すると、同時に実行するのが少し速くなると思っていました。
ノート:私は第五世代i7プロセッサーでこれを実行しているので、私が言われたようゴルーチンが、スレッド上に多重化されている場合、これは両方の同時と平行にする必要があります。
package main
import (
"fmt"
"math"
"strconv"
"time"
)
func main() {
var input string
var sum float64
var pi float64
c := make(chan float64)
fmt.Print("How many iterations? ")
fmt.Scanln(&input)
max,err := strconv.Atoi(input)
if err != nil {
panic("You did not enter a valid integer")
}
start := time.Now() //start timing execution of concurrent routine
for i := 0; i < max; i++ {
go chudnovskyConcurrent(i,c)
}
for i := 0; i < max; i++ {
sum += <-c
}
end := time.Now() //end of concurrent routine
fmt.Println("Duration of concurrent calculation: ",end.Sub(start))
pi = 1/(12*sum)
fmt.Println(pi)
start = time.Now() //start timing execution of syncronous routine
sum = 0
for i := 0; i < max; i++ {
sum += chudnovskySync(i)
}
end = time.Now() //end of syncronous routine
fmt.Println("Duration of synchronous calculation: ",end.Sub(start))
pi = 1/(12*sum)
fmt.Println(pi)
}
func chudnovskyConcurrent(i int, c chan<- float64) {
var numerator float64
var denominator float64
ifloat := float64(i)
iun := uint64(i)
numerator = math.Pow(-1, ifloat) * float64(factorial(6*iun)) * (545140134*ifloat+13591409)
denominator = float64(factorial(3*iun)) * math.Pow(float64(factorial(iun)),3) * math.Pow(math.Pow(640320,3),ifloat+0.5)
c <- numerator/denominator
}
func chudnovskySync(i int) (r float64) {
var numerator float64
var denominator float64
ifloat := float64(i)
iun := uint64(i)
numerator = math.Pow(-1, ifloat) * float64(factorial(6*iun)) * (545140134*ifloat+13591409)
denominator = float64(factorial(3*iun)) * math.Pow(float64(factorial(iun)),3) * math.Pow(math.Pow(640320,3),ifloat+0.5)
r = numerator/denominator
return
}
func factorial(n uint64) (res uint64) {
if (n > 0) {
res = n * factorial(n-1)
return res
}
return 1
}
そして、ここに私の結果は次のとおりです。あなたがやっている
How many iterations? 20
Duration of concurrent calculation: 573.944µs
3.1415926535897936
Duration of synchronous calculation: 63.056µs
3.1415926535897936
goroutinesは安価で、無料ではありません。 'go version'コマンドの出力は何ですか? – peterSO
go version go1.6 linux/amd64 – Keozon
バグ警告:あなたの例である20回の反復は、あなたの階乗関数をオーバーフローさせます。 – peterSO