为了账号安全,请及时绑定邮箱和手机立即绑定

戈朗循环中的并行性

戈朗循环中的并行性

Go
暮色呼如 2022-10-04 19:49:55
我有一个项目,需要在CPU的多个内核上运行它以获得更快的速度。我在福特兰中使用了omplib,但我不熟悉戈朗并行性。我尝试了戈鲁丁,但那是错的,弄得一团糟,我得到了错误的结果。这是我的代码:package mainimport (    "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            }        }
查看完整描述

1 回答

?
蓝山帝景

TA贡献1843条经验 获得超7个赞

以下是两种尝试方法:https://play.golang.org/p/O1uB2zzJEC5

package main


import (

    "fmt"

    "sync"

)


func main() {

  waitGroupApproach()

  channelApproach()

}


func waitGroupApproach() {

    fmt.Println("waitGroupApproach")

    var waitgroup sync.WaitGroup

    

    result_table := make([]int, 6, 6)

    

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

        waitgroup.Add(1)

        

        go func(index int) {

            fmt.Println(index) // try putting here `j` instea of `index`

            result_table[index] = index*2

        

            waitgroup.Done()

        }(j) // you have to put any for-loop variables into closure

        // because otherwsie all routines inside will likely get the last j == n_particles + 1

        // as they will likely run after the loop has finished

    }

    

    fmt.Println("waiting")

    waitgroup.Wait()

    // process results further

    fmt.Println("finished")

    fmt.Println(result_table)

}


func channelApproach() {

    fmt.Println("\nchannelApproach")

    

    type intpos struct {

            x, y, index int

        }


    results := make(chan intpos)


    // initialize routines

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

        go func(index int) {

            // do processing

            results <- intpos{index*2, index*3, index}          

        }(j)

    }

    fmt.Println("Waiting..")

    

    // collect results, iterate the same number of times

    result_table := make([]int, 6)

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

        r := <- results

        // watch out order, migth not be the same as in invocation, 

        // so that's why I store j in results as well

        fmt.Println(r.index, r.x, r.y)

        result_table[r.index] = r.x

    }

    fmt.Println("Finished..")

    fmt.Println(result_table)

}

我更喜欢通道方法,因为它对我来说更像是惯用语,它允许更容易处理恐慌,错误条件等。


查看完整回答
反对 回复 2022-10-04
  • 1 回答
  • 0 关注
  • 63 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信