在下面的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
答案 0 :(得分:1)
我认为您提供的输入文件需要花费很长时间才能被程序读取(通过每行扫描)。