GoLang程序即使使用GOMAXPROCS(4)

时间:2015-11-26 10:28:15

标签: multithreading go goroutine

在下面的GoLang计划中,我试图使用2 * N goroutines(每个男人和女人1个)为N名男性和N名女性实施stable marriage problem

该计划紧密遵循计划定义,因为每个goroutine(阅读"每个人")通过渠道向所需的女性goroutine发送消息,而女性goroutine反过来拒绝/接受他的提议。我希望在设置runtime.GOMAXPROCS(4)时可以在多个线程上轻松调度程序,但它仍然(几乎)在完全相同的时间运行(并且运行linux命令time仍然显示100%的CPU使用率而不是预期的400%

package main

import (
    "fmt"
    "runtime"
    "time"
)

const N = 500

type human struct {
    pref    [N]int
    phone   chan int
    cur_eng int
    cur_num int
    id      int
}

var men = [N]human{}
var women = [N]human{}

func man(id int) {
    guy := &men[id]
    for {
        runtime.Gosched()
        for j := guy.cur_num + 1; j < N; j++ {
            guy.cur_num = j
            girl := &women[guy.pref[guy.cur_num]]
            girl.phone <- guy.id
            msg := <-guy.phone
            if msg == 1 {
                guy.cur_eng = guy.pref[guy.cur_num]
                break
            }
        }
        select {
        case <-guy.phone:
            guy.cur_eng = -1
        }
    }
}

func woman(id int, termi chan bool) {
    girl := &women[id]
    for {

        runtime.Gosched()
        select {
        case msg := <-girl.phone:
            if msg >= 0 {
                if girl.cur_eng == -1 {
                    men[msg].phone <- 1
                    girl.cur_eng = msg
                    termi <- true
                } else if girl.pref[girl.cur_eng] < girl.pref[msg] {
                    men[msg].phone <- 0
                } else {
                    men[msg].phone <- 1
                    men[girl.cur_eng].phone <- -10
                    girl.cur_eng = msg
                }
            }
        }
    }
}

func main() {
    runtime.GOMAXPROCS(8)
    for i := 0; i < N; i++ {
        men[i] = human{pref: [N]int{}, phone: make(chan int), cur_eng: -1, cur_num: -1, id: i}
        for j := 0; j < N; j++ {
            fmt.Scanf("%d\n", &(men[i].pref[j]))
        }
    }
    for i := 0; i < N; i++ {
        women[i] = human{pref: [N]int{}, phone: make(chan int), cur_eng: -1, cur_num: -1, id: i}
        for j := 0; j < N; j++ {
            t := 0
            fmt.Scanf("%d\n", &t)
            women[i].pref[t] = j
        }
    }
    termi := make(chan bool)
    for i := 0; i < N; i++ {
        go man(i)
        go woman(i, termi)
    }
    for i := 0; i < N; i++ {
        <-termi
    }
    time.Sleep(100 * time.Millisecond)
    for i := 0; i < N; i++ {
        fmt.Printf("%d %d\n", i, men[i].cur_eng)
    }
}

编辑:我制作的程序的序列实现是here。时间比较显示两者在几乎相同的时间内运行(序列为1.27s,上述为1.30s)。

此外,并行实现所遵循的算法是根据this进行的,我也能理解(我使用goroutines,因为我不知道如何使用MPI)。 如果可能,请随意建议替代实施(并行)。

上述程序需要以下输入文件:https://drive.google.com/file/d/0B6jsnt965ZwrWlV1OE9LLVA1LUk/view?usp=sharing

1 个答案:

答案 0 :(得分:1)

我认为您提供的输入文件需要花费很长时间才能被程序读取(通过每行扫描)。