147
edits
Changes
→Parallel - Pi
===== Parallel - Pi =====
<syntaxhighlight lang="go">
import ( cpus := "fmt" "math/rand" "runtime.NumCPU(" "time")
// Struct: Stopwatch objecttype StopWatch struct { start, stop time.Time} // Method: Claculate time deltafunc (self *StopWatch) Milliseconds() uint32 { return uint32(self.stop.Sub(self.start) / time.Millisecond)} // Function: Start timerfunc Start() time.Time { return time.Now()} // Function: Stop timerfunc Stop(start time.Time) *StopWatch { watch := StopWatch{start: start, stop: time.Now()} return &watch} // Function: Serial calustion of PIfunc PI(samples int) float64 { var inside int = 0 r := rand.New(rand.NewSource(time.Now().UnixNano())) start := Start() // start timer for i := 0; i < samples; i++ { x := r.Float64() y := r.Float64() if (x*x + y*y) <= 1 { inside++ } } ratio := float64(inside) / float64(samples) ratio = ratio * 4 watch := Stop(start) // stop timer fmt.Printf("Serial - milliseconds elapsed:\t\t\t\t %v\n", watch.Milliseconds()) return ratio} // Function: Concurrent calustion of PIfunc MultiPI(samples int) float64 { cpus := runtime.NumCPU() // getting the numbre of CPUs fmt.Println("\nNumber of CPUs:\t\t\t\t\t\t", cpus) threadSamples := samples / cpus// splitting work among the CPUs
results := make(chan float64, cpus)
start := Start() // start timer
for j := 0; j < cpus; j++ {
go func() {// spawn goroutine
var inside int
r := rand.New(rand.NewSource(time.Now().UnixNano()))
for i := 0; i < threadSamples; i++ {
x, y := r.Float64(), r.Float64()
}
}
results <- float64(inside) / float64(threadSamples) * 4
}()
var total float64
// accumulate the results of reach channel
for i := 0; i < cpus; i++ {
total += <-results
}
}
func main() { fmt.Println("Running Monte Carlo simulations ...\n") fmt.Println("Our value of Pi after 1,000,000,000 runs:\t\t", PI(1000000000)) fmt.Println("Our value of Pi after 1,000,000,000 runs (MT):\t\t", MultiPI(1000000000))}</syntaxhighlight>
===== Parallel execution CPU profile =====