戈朗循环中的并行性

我有一个项目,需要在CPU的多个内核上运行它以获得更快的速度。我在福特兰中使用了omplib,但我不熟悉戈朗并行性。我尝试了戈鲁丁,但那是错的,弄得一团糟,我得到了错误的结果。这是我的代码:


package main


import (

    "bufio"

    "fmt"

    "log"

    "math"

    "math/rand"

    "os"


    "time"

)


const (

    n_particles int     = 2048

    n_steps     int     = 1000000

    dt          float64 = 1.0

    v0          float64 = 0.50

    radius      float64 = 1.0

    f_intensity float64 = 1.8

    scale       float64 = 32.0

    alpha       float64 = 1.0 / 36.0

)


var (

    x      [n_particles + 1]float64

    y      [n_particles + 1]float64

    angles [n_particles + 1]float64

    vx     [n_particles + 1]float64

    vy     [n_particles + 1]float64

    order  [n_steps + 1]float64

)


func main() {

    /////randomizer

    vstart := time.Now()

    rsource := rand.NewSource(time.Now().UnixNano())

    randomizer := rand.New(rsource)


    for i := 0; i <= n_particles; i++ {

        x[i] = (randomizer.Float64()) * scale

        y[i] = (randomizer.Float64()) * scale

        angles[i] = (randomizer.Float64()) * math.Pi * 2

        sin, cos := math.Sincos(angles[i])

        vx[i] = v0 * cos

        vy[i] = v0 * sin

    }

    //////main loop

    for i := 0; i <= n_steps; i++ {

        start := time.Now()


        for j := 0; j <= n_particles; j++ {

            x[j] = x[j] + (vx[j] * dt)

            //x[j] = math.Mod(x[j], scale)

            if x[j] < 0.0 {

                x[j] = x[j] + scale

            }

            if x[j] >= scale {

                x[j] = x[j] - scale

            }

            y[j] = y[j] + (vy[j] * dt)

            //y[j] = math.Mod(x[j], scale)

            if y[j] < 0.0 {

                y[j] = y[j] + scale

            }

            if y[j] >= scale {

                y[j] = y[j] - scale

            }


        }

暮色呼如
浏览 64回答 1
1回答

蓝山帝景

以下是两种尝试方法:https://play.golang.org/p/O1uB2zzJEC5package mainimport (&nbsp; &nbsp; "fmt"&nbsp; &nbsp; "sync")func main() {&nbsp; waitGroupApproach()&nbsp; channelApproach()}func waitGroupApproach() {&nbsp; &nbsp; fmt.Println("waitGroupApproach")&nbsp; &nbsp; var waitgroup sync.WaitGroup&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; result_table := make([]int, 6, 6)&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; for j := 0; j <= 5; j++ {&nbsp; &nbsp; &nbsp; &nbsp; waitgroup.Add(1)&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; go func(index int) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Println(index) // try putting here `j` instea of `index`&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; result_table[index] = index*2&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; waitgroup.Done()&nbsp; &nbsp; &nbsp; &nbsp; }(j) // you have to put any for-loop variables into closure&nbsp; &nbsp; &nbsp; &nbsp; // because otherwsie all routines inside will likely get the last j == n_particles + 1&nbsp; &nbsp; &nbsp; &nbsp; // as they will likely run after the loop has finished&nbsp; &nbsp; }&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; fmt.Println("waiting")&nbsp; &nbsp; waitgroup.Wait()&nbsp; &nbsp; // process results further&nbsp; &nbsp; fmt.Println("finished")&nbsp; &nbsp; fmt.Println(result_table)}func channelApproach() {&nbsp; &nbsp; fmt.Println("\nchannelApproach")&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; type intpos struct {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; x, y, index int&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; results := make(chan intpos)&nbsp; &nbsp; // initialize routines&nbsp; &nbsp; for j := 0; j <= 5; j++ {&nbsp; &nbsp; &nbsp; &nbsp; go func(index int) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // do processing&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; results <- intpos{index*2, index*3, index}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; }(j)&nbsp; &nbsp; }&nbsp; &nbsp; fmt.Println("Waiting..")&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; // collect results, iterate the same number of times&nbsp; &nbsp; result_table := make([]int, 6)&nbsp; &nbsp; for j := 0; j <= 5; j++ {&nbsp; &nbsp; &nbsp; &nbsp; r := <- results&nbsp; &nbsp; &nbsp; &nbsp; // watch out order, migth not be the same as in invocation,&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; // so that's why I store j in results as well&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println(r.index, r.x, r.y)&nbsp; &nbsp; &nbsp; &nbsp; result_table[r.index] = r.x&nbsp; &nbsp; }&nbsp; &nbsp; fmt.Println("Finished..")&nbsp; &nbsp; fmt.Println(result_table)}我更喜欢通道方法,因为它对我来说更像是惯用语,它允许更容易处理恐慌,错误条件等。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go