我在Go中分配了一个代码,以并行处理给定的代码循环。我不确定我的代码是否并行。
我试图简单地将数组分成两半,并对这两个半部分使用go例程。
package main
import (
"fmt"
"math"
)
type Body struct {
x, y, vx, vy, mass float64
r, g, b uint
}
func main() {
var count uint
var radius float64
done := make(chan bool)
fmt.Scan(&count, &radius)
bodies := make([]Body, count)
for i := range bodies {
b := &bodies[i]
fmt.Scan(&b.x, &b.y, &b.vx, &b.vy, &b.mass, &b.r, &b.g, &b.b)
}
updatedBodies := make([]Body, count)
copy(updatedBodies, bodies)
mid := len(updatedBodies)/2
go func(){
for i := range updatedBodies[mid:] {
b := &updatedBodies[i+mid]
for _, ob := range bodies {
dx, dy := ob.x - b.x, ob.y - b.y
if dist := math.Sqrt(dx*dx + dy*dy); dist > 1 { // far enough
accel := 0.0000000000667 * ob.mass / (dist * dist * dist)
b.vx += accel * dx
b.vy += accel * dy
}
}
b.x += b.vx
b.y += b.vy
}
done <- true
}()
go func(){
for i := range updatedBodies[:mid] {
b := &updatedBodies[i]
for _, ob := range bodies {
dx, dy := ob.x - b.x, ob.y - b.y
if dist := math.Sqrt(dx*dx + dy*dy); dist > 1 { // far enough
accel := 0.0000000000667 * ob.mass / (dist * dist * dist)
b.vx += accel * dx
b.vy += accel * dy
}
}
b.x += b.vx
b.y += b.vy
}
done <- true
}()
<- done
<- done
fmt.Println(count)
fmt.Println(radius)
for _, b := range updatedBodies {
fmt.Println(b.x, b.y, b.vx, b.vy, b.mass, b.r, b.g, b.b)
}
}
for i := range updatedBodies {
b := &updatedBodies[i]
for _, ob := range bodies {
dx, dy := ob.x - b.x, ob.y - b.y
if dist := math.Sqrt(dx*dx + dy*dy); dist > 1 { // far enough
accel := 0.0000000000667 * ob.mass / (dist * dist * dist)
b.vx += accel * dx
b.vy += accel * dy
}
}
b.x += b.vx
b.y += b.vy
}
我问了一位教授有关他说的代码的问题,他说我必须递归运行go例程以使循环并行。
答案 0 :(得分:1)
您的代码确实可以并发运行*,但不一定以最佳方式运行。本质上,您已经将工作负载分为两部分,并且同时运行了两半。
[教授]说,我必须递归运行go例程以使循环并行。
这是不正确的,但我不知道您的教授说的确切话,因此他可能没有对您说谎。他显然在考虑某种递归解决方案。我不会在这里使用递归,但这只是一种方式。
很难提供您的教授正在寻找的答案。最好的建议是请您的教授解释他的意图。
*并发不是并行性。请阅读/观看this。