dongshenchi5364 2016-08-21 04:41
浏览 104
已采纳

Golang中的并发积分计算

I tried to compute the integral concurrently, but my program ended up being slower than computing the integral with a normal for loop. What am I doing wrong?

package main

import (
    "fmt"
    "math"
    "sync"
    "time"
)

type Result struct {
    result float64
    lock sync.RWMutex
}

var wg sync.WaitGroup
var result Result

func main() {
    now := time.Now()
    a := 0.0
    b := 1.0
    n := 100000.0
    deltax := (b - a) / n
    wg.Add(int(n))
    for i := 0.0; i < n; i++ {
        go f(a, deltax, i)
    }
    wg.Wait()
    fmt.Println(deltax * result.result)
    fmt.Println(time.Now().Sub(now))
}

func f(a float64, deltax float64, i float64) {
    fx := math.Sqrt(a + deltax * (i + 0.5))
    result.lock.Lock()
    result.result += fx
    result.lock.Unlock()
    wg.Done()
}
  • 写回答

2条回答 默认 最新

  • dongqing8765 2016-08-21 06:01
    关注

    Unless the time taken by the activity in the goroutine takes a lot more time than needed to switch contexts, carry out the task and use a mutex to update a value, it would be faster to do it serially.

    Take a look at a slightly modified version. All I've done is add a delay of 1 microsecond in the f() function.

    package main
    
    import (
        "fmt"
        "math"
        "sync"
        "time"
    )
    
    type Result struct {
        result float64
        lock   sync.RWMutex
    }
    
    var wg sync.WaitGroup
    var result Result
    
    func main() {
        fmt.Println("concurrent")
        concurrent()
        result.result = 0
        fmt.Println("serial")
        serial()
    }
    
    func concurrent() {
        now := time.Now()
        a := 0.0
        b := 1.0
        n := 100000.0
        deltax := (b - a) / n
        wg.Add(int(n))
        for i := 0.0; i < n; i++ {
            go f(a, deltax, i, true)
        }
        wg.Wait()
        fmt.Println(deltax * result.result)
        fmt.Println(time.Now().Sub(now))
    }
    
    func serial() {
        now := time.Now()
        a := 0.0
        b := 1.0
        n := 100000.0
        deltax := (b - a) / n
        for i := 0.0; i < n; i++ {
            f(a, deltax, i, false)
        }
        fmt.Println(deltax * result.result)
        fmt.Println(time.Now().Sub(now))
    }
    
    func f(a, deltax, i float64, concurrent bool) {
        time.Sleep(1 * time.Microsecond)
        fx := math.Sqrt(a + deltax*(i+0.5))
        if concurrent {
            result.lock.Lock()
            result.result += fx
            result.lock.Unlock()
            wg.Done()
        } else {
            result.result += fx
        }
    }
    

    With the delay, the result was as follows (the concurrent version is much faster):

    concurrent
    0.6666666685900424
    624.914165ms
    
    serial
    0.6666666685900422
    5.609195767s
    

    Without the delay:

    concurrent
    0.6666666685900428
    50.771275ms
    
    serial
    0.6666666685900422
    749.166µs
    

    As you can see, the longer it takes to complete a task, the more sense it makes to do it concurrently, if possible.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 R语言Rstudio突然无法启动
  • ¥15 关于#matlab#的问题:提取2个图像的变量作为另外一个图像像元的移动量,计算新的位置创建新的图像并提取第二个图像的变量到新的图像
  • ¥15 改算法,照着压缩包里边,参考其他代码封装的格式 写到main函数里
  • ¥15 用windows做服务的同志有吗
  • ¥60 求一个简单的网页(标签-安全|关键词-上传)
  • ¥35 lstm时间序列共享单车预测,loss值优化,参数优化算法
  • ¥15 Python中的request,如何使用ssr节点,通过代理requests网页。本人在泰国,需要用大陆ip才能玩网页游戏,合法合规。
  • ¥100 为什么这个恒流源电路不能恒流?
  • ¥15 有偿求跨组件数据流路径图
  • ¥15 写一个方法checkPerson,入参实体类Person,出参布尔值