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.