doxd96148 2017-11-18 13:29
浏览 22

gccgo的并发问题

I've just landed in the the GO-sphere, so, as usually, I'm trying to implement some of the classics in the new language to make some comparison.

I'm experiencing a strange situation with the Montecarlo Simulation for PI, using concurrency:

  • when I compile the code using gc, for any number of events value (nevents) I provided all the goroutines starts simultaneously and all works as expected (even if "concurrency is not parallelism", I know)
  • when I compile the code using gccgo, it works as above when nevents is less or equal than ~10.000.000, but for bigger values each goroutine starts when the previous one has almost finished and this behaviour is more obvious the bigger nvalues gets (~100.000.000)

What am I missing? Be good, It's my first week with Go!


Here's the code:

package main

import ("os"
        "fmt"
        "log"
        "strconv"
        "math"
        "math/rand"
        "time"
)

var (ncpus         int     = 2
     threadspercpu int     = 2
     ngophers      int     = ncpus*threadspercpu
     rayu          float64 = 1.0
)

func montecarlo(returnvalues chan int, gevents int, id int) {
    // debug
           fmt.Println("goroutine started")
    randgen := rand.New(rand.NewSource(time.Now().UnixNano() + 
               int64(id*id + 1)))
    insidecircle := 0
    for i := 0; i < gevents; i++ {
        if (math.Pow(randgen.Float64(), 2.0) +
            math.Pow(randgen.Float64(), 2.0)) < rayu {
            insidecircle++
        }
    }

    // debug {
           time.Sleep(time.Duration(id)*time.Second)
           fmt.Println("goroutine finished")
    // }
    returnvalues <- insidecircle
}

func main() {
    arg := os.Args[1]
    nevents64, err := strconv.ParseInt(arg, 10, 32)
    if (err != nil || nevents64 < 1) {
        log.Fatalf("Invalid number of cases provided: '%s'", arg)
    }
    nevents      := int(nevents64)
    returnvalues := make(chan int)
    gopherevents := nevents / ngophers

    for i := 0; i < ngophers-1; i++ {
        go montecarlo(returnvalues, gopherevents, i)
    }
    remaining := gopherevents + (nevents % ngophers)
    go montecarlo(returnvalues, remaining, ngophers-1)

    insidecircle_events := 0
    for i := 0; i < ngophers; i++ {
        insidecircle_events += <- returnvalues
    }

    fmt.Println("pi: ", (float64(insidecircle_events) / 
                         float64(nevents) * 4))
}

I've added a time delay to facilitate the debugging.

  • 写回答

0条回答 默认 最新

    报告相同问题?

    悬赏问题

    • ¥60 求一个简单的网页(标签-安全|关键词-上传)
    • ¥35 lstm时间序列共享单车预测,loss值优化,参数优化算法
    • ¥15 基于卷积神经网络的声纹识别
    • ¥15 Python中的request,如何使用ssr节点,通过代理requests网页。本人在泰国,需要用大陆ip才能玩网页游戏,合法合规。
    • ¥100 为什么这个恒流源电路不能恒流?
    • ¥15 有偿求跨组件数据流路径图
    • ¥15 写一个方法checkPerson,入参实体类Person,出参布尔值
    • ¥15 我想咨询一下路面纹理三维点云数据处理的一些问题,上传的坐标文件里是怎么对无序点进行编号的,以及xy坐标在处理的时候是进行整体模型分片处理的吗
    • ¥15 CSAPPattacklab
    • ¥15 一直显示正在等待HID—ISP