FAQ
Hello fellow Gophers,

yeah I know proposals always lead to flamewars. Still let's try again. I
propose to introduce a special channel send (or channel type) that advises
the runtime to yield control to the goroutine that receives from the
channel. First notice that ignoring this advice and doing normal channel
behaviour is still correct.
The send might look something like "mychan <!- value" so it would be a
syntax change but one not influencing existing Go programs.

This would be especially helpful in a case where we send a reply channel
over a channel and wait on that for the other goroutine to reply, because
it yields back on the reply
we might even be able to do the whole operation in a single OS timeslice
without any kernel context switch. As I understand it this would be
similiar to
QNX' MsgSend. The reason I think we need special syntax is because there is
no way I can think of a compiler can possibly know whether I want
to just send something over a channel and go on minding my own business or
whether my progress depends on the receiving goroutine

Greetings Niklas

--
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+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Search Discussions

  • Jan Mercl at Feb 20, 2013 at 3:21 pm

    On Wed, Feb 20, 2013 at 4:03 PM, Niklas Schnelle wrote:
    QNX' MsgSend. The reason I think we need special syntax is because there is
    no way I can think of a compiler can possibly know whether I want
    to just send something over a channel and go on minding my own business or
    whether my progress depends on the receiving goroutine
    When you are blocked in a channel receive, then the runtime knows
    perfectly what the process is waiting for. But then again, introducing
    priorities, even "normal" and "higher" is a concept which requires, if
    considered at all to be included in Go, probably a much more serious
    analysis of the whole problem and the possible approaches to it.

    Anyway, hints on the send operation which should prioritize a receive
    operation seem to me like doing it backwardly.

    -j

    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Niklas Schnelle at Feb 20, 2013 at 3:40 pm
    It's not about prioritising the receive. It's the send that says "I'm done
    here, nothing left to do hand control to the other end". But I guess my
    thinking failed on another point I forgot that a send with buffer size one
    blocks. Didn't know it actually yield to the correct go routine.
    On Feb 20, 2013 4:14 PM, "Jan Mercl" wrote:

    On Wed, Feb 20, 2013 at 4:03 PM, Niklas Schnelle
    wrote:
    QNX' MsgSend. The reason I think we need special syntax is because there is
    no way I can think of a compiler can possibly know whether I want
    to just send something over a channel and go on minding my own business or
    whether my progress depends on the receiving goroutine
    When you are blocked in a channel receive, then the runtime knows
    perfectly what the process is waiting for. But then again, introducing
    priorities, even "normal" and "higher" is a concept which requires, if
    considered at all to be included in Go, probably a much more serious
    analysis of the whole problem and the possible approaches to it.

    Anyway, hints on the send operation which should prioritize a receive
    operation seem to me like doing it backwardly.

    -j
    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Niklas Schnelle at Feb 20, 2013 at 3:49 pm
    My bad misread again the receive actually yields. Consider this solved
    On Feb 20, 2013 4:39 PM, "Niklas Schnelle" wrote:

    It's not about prioritising the receive. It's the send that says "I'm done
    here, nothing left to do hand control to the other end". But I guess my
    thinking failed on another point I forgot that a send with buffer size one
    blocks. Didn't know it actually yield to the correct go routine.
    On Feb 20, 2013 4:14 PM, "Jan Mercl" wrote:

    On Wed, Feb 20, 2013 at 4:03 PM, Niklas Schnelle
    wrote:
    QNX' MsgSend. The reason I think we need special syntax is because there is
    no way I can think of a compiler can possibly know whether I want
    to just send something over a channel and go on minding my own business or
    whether my progress depends on the receiving goroutine
    When you are blocked in a channel receive, then the runtime knows
    perfectly what the process is waiting for. But then again, introducing
    priorities, even "normal" and "higher" is a concept which requires, if
    considered at all to be included in Go, probably a much more serious
    analysis of the whole problem and the possible approaches to it.

    Anyway, hints on the send operation which should prioritize a receive
    operation seem to me like doing it backwardly.

    -j
    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Kevin Gillette at Feb 20, 2013 at 8:26 pm
    go func(val int) { ch <- val }(val)
    On Wednesday, February 20, 2013 8:39:54 AM UTC-7, Niklas Schnelle wrote:

    It's not about prioritising the receive. It's the send that says "I'm done
    here, nothing left to do hand control to the other end". But I guess my
    thinking failed on another point I forgot that a send with buffer size one
    blocks. Didn't know it actually yield to the correct go routine.
    On Feb 20, 2013 4:14 PM, "Jan Mercl" <0xj...@gmail.com <javascript:>>
    wrote:
    On Wed, Feb 20, 2013 at 4:03 PM, Niklas Schnelle
    <niklas....@gmail.com <javascript:>> wrote:
    QNX' MsgSend. The reason I think we need special syntax is because there is
    no way I can think of a compiler can possibly know whether I want
    to just send something over a channel and go on minding my own business or
    whether my progress depends on the receiving goroutine
    When you are blocked in a channel receive, then the runtime knows
    perfectly what the process is waiting for. But then again, introducing
    priorities, even "normal" and "higher" is a concept which requires, if
    considered at all to be included in Go, probably a much more serious
    analysis of the whole problem and the possible approaches to it.

    Anyway, hints on the send operation which should prioritize a receive
    operation seem to me like doing it backwardly.

    -j
    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • John Nagle at Feb 20, 2013 at 9:16 pm

    On 2/20/2013 7:39 AM, Niklas Schnelle wrote:
    It's not about prioritising the receive. It's the send that says "I'm done
    here, nothing left to do hand control to the other end". But I guess my
    thinking failed on another point I forgot that a send with buffer size one
    blocks. Didn't know it actually yield to the correct go routine.
    I think that applies to buffer size zero. A send on a buffer of size
    zero is effectively a coroutine call.

    John Nagle

    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Dmitry Vyukov at Feb 20, 2013 at 3:33 pm

    On Wed, Feb 20, 2013 at 7:03 PM, Niklas Schnelle wrote:

    Hello fellow Gophers,

    yeah I know proposals always lead to flamewars. Still let's try again. I
    propose to introduce a special channel send (or channel type) that advises
    the runtime to yield control to the goroutine that receives from the
    channel. First notice that ignoring this advice and doing normal channel
    behaviour is still correct.
    The send might look something like "mychan <!- value" so it would be a
    syntax change but one not influencing existing Go programs.

    This would be especially helpful in a case where we send a reply channel
    over a channel and wait on that for the other goroutine to reply, because
    it yields back on the reply
    we might even be able to do the whole operation in a single OS timeslice
    without any kernel context switch. As I understand it this would be
    similiar to
    QNX' MsgSend. The reason I think we need special syntax is because there
    is no way I can think of a compiler can possibly know whether I want
    to just send something over a channel and go on minding my own business or
    whether my progress depends on the receiving goroutine
    Currently

    reqc <- m
    r := <-m.respc

    does exactly what you ask for -- block current goroutine, switch to the
    receiving goroutine, and then switch back, all without kernel context
    switch.

    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • John Nagle at Feb 20, 2013 at 9:32 pm

    On 2/20/2013 7:27 AM, Dmitry Vyukov wrote:

    Currently

    reqc <- m
    r := <-m.respc

    does exactly what you ask for -- block current goroutine, switch to the
    receiving goroutine, and then switch back, all without kernel context
    switch.
    Does it? Assuming the channels involved have zero length, and
    the receiving coroutine is blocked and waiting on "reqc", then
    the first line is a coroutine handoff. As soon as the receiver
    starts, the sender is unblocked and becomes ready to run.

    In the single-CPU (or single thread) case, the sender won't
    run yet. When the receiver goroutine gets done and sends to
    "m.respc", the receiver goroutine blocks. But there's nobody
    waiting at "r := <-m.respc" yet. So the Go dispatch loop has
    to be executed, and if the sending goroutine is at the front
    of the line, it gets restarted, hits "r := <-m.respc",
    gets the data, and proceeds.

    This is fine as long as there are no other goroutines
    waiting for some CPU time. If there are, they may get control
    next, and the sending goroutine here has to wait until they
    finish.

    Try testing the case where you have a CPU-bound goroutine
    running in the "background" while two other goroutines are
    throwing control back and forth across channels. How badly
    does the compute-bound goroutine impact messaging performance.
    This needs to be tried for both the single-thread and multi-thread
    cases, so the Playground isn't a suitable test area.

    QNX's MsgSend mechanism is a send and wait for reply primitive,
    which gets around this problem. I've had real-time programs running
    under QNX, passing messages back and forth constantly, while doing
    compiles in the background. The compiles don't hurt the real time
    performance.

    Mach, with unidirectional channels, go this wrong, which is
    the source of most of the opinion that message-passing microkernels
    are bad.

    This will only matter if someone tries to do real time work
    or game development in Go.

    John Nagle



    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Kyle Lemons at Feb 20, 2013 at 11:37 pm
    Given two goroutines of the genreal form

    cmd <- req
    // possibly do stuff
    resp := <-req.response
    ----
    c := <-cmd
    // do work
    c.response <- result

    It's hard to have more than one "in place" handoff. Either the "cmd <-
    req" hands off to "c := <-cmd" or "c.response <- result" hands off to "resp
    := <-req.response" -- the other will not be blocked in the correct place.

    On Wed, Feb 20, 2013 at 1:31 PM, John Nagle wrote:
    On 2/20/2013 7:27 AM, Dmitry Vyukov wrote:

    Currently

    reqc <- m
    r := <-m.respc

    does exactly what you ask for -- block current goroutine, switch to the
    receiving goroutine, and then switch back, all without kernel context
    switch.
    Does it? Assuming the channels involved have zero length, and
    the receiving coroutine is blocked and waiting on "reqc", then
    the first line is a coroutine handoff. As soon as the receiver
    starts, the sender is unblocked and becomes ready to run.

    In the single-CPU (or single thread) case, the sender won't
    run yet. When the receiver goroutine gets done and sends to
    "m.respc", the receiver goroutine blocks. But there's nobody
    waiting at "r := <-m.respc" yet. So the Go dispatch loop has
    to be executed, and if the sending goroutine is at the front
    of the line, it gets restarted, hits "r := <-m.respc",
    gets the data, and proceeds.

    This is fine as long as there are no other goroutines
    waiting for some CPU time. If there are, they may get control
    next, and the sending goroutine here has to wait until they
    finish.

    Try testing the case where you have a CPU-bound goroutine
    running in the "background" while two other goroutines are
    throwing control back and forth across channels. How badly
    does the compute-bound goroutine impact messaging performance.
    This needs to be tried for both the single-thread and multi-thread
    cases, so the Playground isn't a suitable test area.

    QNX's MsgSend mechanism is a send and wait for reply primitive,
    which gets around this problem. I've had real-time programs running
    under QNX, passing messages back and forth constantly, while doing
    compiles in the background. The compiles don't hurt the real time
    performance.

    Mach, with unidirectional channels, go this wrong, which is
    the source of most of the opinion that message-passing microkernels
    are bad.

    This will only matter if someone tries to do real time work
    or game development in Go.

    John Nagle



    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.

    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Dmitry Vyukov at Feb 21, 2013 at 5:02 am

    On Thu, Feb 21, 2013 at 1:31 AM, John Nagle wrote:
    On 2/20/2013 7:27 AM, Dmitry Vyukov wrote:

    Currently

    reqc <- m
    r := <-m.respc

    does exactly what you ask for -- block current goroutine, switch to the
    receiving goroutine, and then switch back, all without kernel context
    switch.
    Does it? Assuming the channels involved have zero length, and
    Don't use zero length channels if you care about performance.
    the receiving coroutine is blocked and waiting on "reqc", then
    the first line is a coroutine handoff. As soon as the receiver
    starts, the sender is unblocked and becomes ready to run.

    In the single-CPU (or single thread) case, the sender won't
    run yet. When the receiver goroutine gets done and sends to
    "m.respc", the receiver goroutine blocks. But there's nobody
    waiting at "r := <-m.respc" yet. So the Go dispatch loop has
    to be executed, and if the sending goroutine is at the front
    of the line, it gets restarted, hits "r := <-m.respc",
    gets the data, and proceeds.

    This is fine as long as there are no other goroutines
    waiting for some CPU time. If there are, they may get control
    next, and the sending goroutine here has to wait until they
    finish.

    Try testing the case where you have a CPU-bound goroutine
    running in the "background" while two other goroutines are
    throwing control back and forth across channels. How badly
    does the compute-bound goroutine impact messaging performance.
    This needs to be tried for both the single-thread and multi-thread
    cases, so the Playground isn't a suitable test area.

    QNX's MsgSend mechanism is a send and wait for reply primitive,
    which gets around this problem. I've had real-time programs running
    under QNX, passing messages back and forth constantly, while doing
    compiles in the background. The compiles don't hurt the real time
    performance.

    Mach, with unidirectional channels, go this wrong, which is
    the source of most of the opinion that message-passing microkernels
    are bad.

    This will only matter if someone tries to do real time work
    or game development in Go.

    John Nagle



    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedFeb 20, '13 at 3:03p
activeFeb 21, '13 at 5:02a
posts10
users6
websitegolang.org

People

Translate

site design / logo © 2022 Grokbase