2 回答

TA貢獻2011條經驗 獲得超2個贊
您正在執行的計算太簡單了,無法在單獨的 goroutine 中進行每一項計算。與實際計算相比,您在運行時(創建 goroutine、多路復用、調度等)浪費的時間更多。您正在嘗試做的更適合 GPU,例如,在那里您擁有大量并行執行單元,可以在瞬間完成這些簡單的計算。但是你需要其他語言和 API 來做到這一點。
您可以做的是為每個硬件執行線程創建軟件執行線程。您想將max變量分成大塊并并行執行。這是一個非常簡單的例子,只是為了說明這個想法:
package main
import (
"fmt"
"math"
"strconv"
"time"
"runtime"
)
func main() {
var input string
var sum float64
var pi float64
c := make(chan float64, runtime.GOMAXPROCS(-1))
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 < runtime.GOMAXPROCS(-1); i++ {
go func(i int){
var sum float64
for j := 0; j < max/runtime.GOMAXPROCS(-1); j++ {
sum += chudnovskySync(j + i*max/runtime.GOMAXPROCS(-1))
}
c <- sum
}(i)
}
for i := 0; i < runtime.GOMAXPROCS(-1); 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 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
}
這是結果
$ go version
go version go1.5.2 windows/amd64
$ go run main.go
GOMAXPROCS = 4
How many iterations? 10000
Duration of concurrent calculation: 932.8916ms
NaN
Duration of synchronous calculation: 2.0639744s
NaN

TA貢獻1872條經驗 獲得超4個贊
我同意,您的計算沒有做足夠的處理來克服擁有多個 goroutine 的開銷。只是為了好玩,在返回結果之前,我修改了您的代碼以進行多次計算(1000、10000、100000、1000000)。我在四核 Xeon 上運行的 Mac OS X Yosemite 下運行了這個(20 次迭代),并且如您所料,同步版本的時間大約是并行版本的四倍。
我注意到的一件有趣的事情是,在大量重復的情況下,同步版本的時間實際上是并行版本的四倍多。我猜這與 Intel 的超線程架構有關,該架構允許在每個內核中實現某種程度的并行性,但我不確定這一點。
- 2 回答
- 0 關注
- 194 瀏覽
添加回答
舉報