just to be sure: you *do* actually use an RT kernel? I know you can set ff 
on stock non-RT kernels, but the results can be quite different.

On Thursday, September 26, 2024 at 5:49:53 AM UTC+2 Zhao Weng wrote:

> 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 golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/11ce3e6b-a8c7-4f4a-8431-4057fd604b8dn%40googlegroups.com.

Reply via email to