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)。
在下面的 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)。