GoLang 程序在单线程上执行,即使使用 GOMAXPROCS(4)

GoLang program executing on single thread even with GOMAXPROCS(4)

在下面的 GoLang 程序中,我试图为 N 男和 N 女实现 stable marriage problem,使用 2*N goroutines(男和女各 1 个)。

程序严格遵循程序定义,因为每个 goroutine(读取 "each man")通过通道向所需的女性 goroutine 发送消息,后者又 rejects/accepts 他的提议。我希望该程序可以在设置 runtime.GOMAXPROCS(4) 时轻松地安排在多个线程上,但是它仍然(几乎)在完全相同的时间运行(并且 运行 linux 命令 time 仍然显示CPU 在 100% 的使用而不是预期的 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

我认为您提供的输入文件需要花费那么多时间才能被程序读取(每行通过 scanf)。