What I found interesting is with this code run with raw on FreeBSD takes ~1s, however running via truss to see what happening with the syscalls it takes only ~83ms e.g.

> ./tst
2018/04/03 21:53:28 Finished in 998.77123ms.
> truss -o t.txt ./tst
2018/04/03 21:53:31 Finished in 83.14988ms.

This only seems to effect really small duration's, time.Millisecond isn't effected, which is perplexing.

On 03/04/2018 21:24, jake6...@gmail.com wrote:
For what it is worth, when I run your new code (without channels) on windows it takes consistently 1 second. On Linux it takes variably between 400ms and 1.5 seconds. Both running go 1.10. But, on my systems, this seems to be actually measuring |time.Sleep()|. Removing the call to |spin()| and the second |runtime.Gosched() |results in the same times:

|
package main

import (
    "log"
    "runtime"
    "time"
)

func main() {
    runtime.GOMAXPROCS(1)

    t0 := time.Now()
    for i := 0; i < 1000; i++ {
        time.Sleep(1 * time.Microsecond)
    }

    log.Printf("Finished in %v.", time.Since(t0))
}
|

I can not speak for your original example, but in this one I would be looking to |time.Sleep()|.

- Jake


On Tuesday, April 3, 2018 at 2:12:40 PM UTC-4, brianbl...@gmail.com wrote:

    Hi Dave, thanks for the reply!

    It makes sense that the send c <- 0 is not guaranteed to transfer
    control to the receiving goroutine. But is it not guaranteed that
    runtime.Gosched() will at least check if another goroutine is
    runnable? I thought that was roughly the point of runtime.Gosched().

    I see what you're saying in that when the second goroutine calls
    Gosched, the sleep period may not be finished. But this will only
    waste another 100 microseconds by design (not 100 milliseconds),
    so it seems like control flow should return to the main goroutine
    approximately when the sleep call finishes.

    I created a simpler example, that doesn't use channels and avoids
    the work length ambiguity, posted below. Now the secondary
    goroutine just does an infinite loop of runtime.Gosched(). It
    should be instantaneous to run (and is on my Mac), but it takes
    almost exactly 5 seconds on Ubuntu, suggesting that there is some
    fixed 5 millisecond delay on Gosched(). And adding a print above
    spin's Gosched makes it instantaneous.

    Thanks for your patience! I'm working on an application where the
    ~5ms Gosched delay is meaningful and I am very curious to figure
    out what's going on here.
    |
    package main

    import (
        "log"
        "runtime"
        "time"
    )

    func spin() {
        for {
            runtime.Gosched()
        }
    }

    func main() {
        runtime.GOMAXPROCS(1)
        go spin()

        t0 := time.Now()
        for i := 0; i < 1000; i++ {
            time.Sleep(10 * time.Microsecond)

            runtime.Gosched()
        }

        log.Printf("Finished in %v.", time.Since(t0))
    }
    |


    On Tuesday, April 3, 2018 at 12:56:49 AM UTC-4,
    brianbl...@gmail.com wrote:

        I've run into some mysterious behavior, where Gosched() works
        as expected in Mac OS X, but only works as expected in Ubuntu
        if I put a logging statement before it.

        I originally posted this on Stack Overflow but was directed
        here. Post:
        
https://stackoverflow.com/questions/49617451/golang-scheduler-mystery-linux-vs-mac-os-x
        
<https://stackoverflow.com/questions/49617451/golang-scheduler-mystery-linux-vs-mac-os-x>

        Any help would be greatly appreciated! Very curious what's
        going on here, as this behavior came up while I was trying to
        write a websocket broadcast server. Here's a minimal setup
        that reproduces the behavior:

        The main goroutine sleeps for 1000 periods of 1ms, and after
        each sleep pushes a dummy message onto another goroutine via a
        channel. The second goroutine listens for new messages, and
        every time it gets one it does 10ms of work. So without any
        |runtime.Gosched()| calls, the program will take 10 seconds to
        run.

        When I add periodic |runtime.Gosched()| calls in the second
        goroutine, as expected the program runtime shrinks down to 1
        second on my Mac. However, when I try running the same program
        on Ubuntu, it still takes 10 seconds. I made sure to set
        |runtime.GOMAXPROCS(1)| in both cases.

        Here's where it gets really strange: if I just add a logging
        statement before the the |runtime.Gosched()| calls, then
        suddenly the program runs in the expected 1 second on Ubuntu
        as well.


        |packagemain import("time""log""runtime")func doWork(c chan
        int){for{<-c // This outer loop will take ~10ms.forj :=0;j
        <100;j++{// The following block of CPU work takes ~100
        microsecondsfori :=0;i <300000;i++{_ =i *17}// Somehow this
        print statement saves the day in
        Ubuntulog.Printf("donkey")runtime.Gosched()}}}func
        main(){runtime.GOMAXPROCS(1)c :=make(chan int,1000)go
        doWork(c)start :=time.Now().UnixNano()fori :=0;i
        <1000;i++{time.Sleep(1*time.Millisecond)// Queue up 10ms of
        work in the other goroutine, which will backlog// this
        goroutine without runtime.Gosched() calls.c <-0}// Whole
        program should take about 1 second to run if the Gosched()
        calls // work, otherwise 10 seconds.log.Printf("Finished in %f
        seconds.",float64(time.Now().UnixNano()-start)/1e9)}|

        ||


--
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 <mailto:golang-nuts+unsubscr...@googlegroups.com>.
For more options, visit https://groups.google.com/d/optout.

--
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.
For more options, visit https://groups.google.com/d/optout.

Reply via email to