Hi gophers,
I'm doing a research on how to prioritise some goroutines over others.So I
can allocate more CPU resource to more important part of the program.
I try to do it by calling runtime.LockOSThread to assign the goroutine
needs to be prioritise to a designated OS thread, and unix.SchedSetAttr to
prioritise that OS thread. Here is the code:
```go
package main
import (
"flag"
"fmt"
"runtime"
"sync"
"time"
"golang.org/x/sys/unix"
)
var (
nPrioritizedGoroutines = flag.Int("p", 1, "# of prioritized goroutines")
nNormalGoroutines = flag.Int("n", 1, "# of normal goroutines")
restDuration = flag.Duration("r", 0, "rest for a certain amount of time
between works")
)
func prioritizeThread() {
// set thread priority to the highest
a := unix.SchedAttr{
Size: unix.SizeofSchedAttr,
Policy: 1,
Priority: 99,
}
if err := unix.SchedSetAttr(0, &a, 0); err != nil {
panic(err)
}
}
func doWorks(workerId int) {
t := time.Now()
for i := 0; i < 100; i++ {
st := time.Now()
res := 0
for ii := 0; ii < 1e9; ii++ {
res += ii
}
fmt.Printf("%d@%d, timecost: %s, res: %d \n", workerId, unix.Gettid(), time.
Since(st), res)
// sleep for a while to simulate gaps between requests.
if *restDuration > 0 {
time.Sleep(*restDuration)
}
}
fmt.Printf("total execute time for worker: %d is %s\n", workerId, time.Since
(t))
}
func main() {
flag.Parse()
runtime.GOMAXPROCS(*nPrioritizedGoroutines)
var wg sync.WaitGroup
workerId := 0
for i := 0; i < *nPrioritizedGoroutines; i++ {
wg.Add(1)
go func(workerId int) {
// assign goroutine to a designated thread
runtime.LockOSThread()
// prioritize this thread
prioritizeThread()
defer wg.Done()
doWorks(workerId)
}(workerId)
workerId++
}
for i := 0; i < *nNormalGoroutines; i++ {
wg.Add(1)
go func(workerId int) {
defer wg.Done()
doWorks(workerId)
}(workerId)
workerId++
}
wg.Wait()
}
```
compile on linux, and run with command `sudo ./sche`, it seems not working,
CPU resource is shared by two thread, and two goroutine execute `doWorks`
in similar timecost(1.5 seconds).
sudo ./sche
1@255429, timecost: 1.475347182s, res: 499999999500000000
0@255425, timecost: 1.517077413s, res: 499999999500000000
1@255429, timecost: 1.473167148s, res: 499999999500000000
0@255425, timecost: 1.515322146s, res: 499999999500000000
1@255429, timecost: 1.494751901s, res: 499999999500000000
0@255425, timecost: 1.532692691s, res: 499999999500000000
while with 1 goroutine only, the timecost will be 0.75 seconds
sudo ./sche -n 0
0@257072, timecost: 751.18938ms, res: 499999999500000000
0@257072, timecost: 747.364725ms, res: 499999999500000000
0@257072, timecost: 745.362553ms, res: 499999999500000000
0@257072, timecost: 748.353778ms, res: 499999999500000000
Am I doing anything wrong here?
Zhao Weng
--
You received this message because you are subscribed to the Google Groups
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/golang-nuts/a1c6c11b-7f85-4807-90b5-609f40421ff6n%40googlegroups.com.