On Saturday, 26 November 2016 08:00:24 UTC+11, Roger Alsing wrote:
>
> So it works very similar to normal OS thread context switching, but more 
> explicit?
>

Yes, goroutine switching occurs a known points; effectively where the 
goroutine is blocked from proceeding; sending and receiving on channels (if 
they are full/empty respectively), trying to acquire a locked mutex, and 
performing IO. These operations happen frequently in a program that 
interacts with others so things more or less work out.
 

> The code will push all local state to the go routine stack, pop the state 
> for the next go routine and change the stack pointer?
>

The cute thing is the Go function call convention is caller save, so when a 
goroutine enters the scheduler there is no state to be saved, it's already 
saved on the stack by the normal function call convention. As Ian said 
above the scheduler just finds the SP and PC for a new goroutine and swaps 
them for the current one. The new goroutine awakes at the bottom of the 
scheduler, and returns to its original control flow.
 

>
> And this is cheaper than context switching as threads have their own 1 or 
> 4 mb stack allocated while go routines have a linked list for its stack 
> (afaik?) ?
>

Goroutines used to have a linked list of stack segments, we dropped that in 
Go 1.3 (might have been 1.2, i'd have to check), now stack segments grow 
and shrink with a cheap check in the preamble of the function; if there 
isn't enough stack to perform the function (this is known precisely at 
compile time), then the function traps into a slow path that doubles the 
stack allocation by copying the whole stack to a new area, then restarts 
the function. Stack shrinking is handled via the GC cycle when a goroutine 
has a large amount of unused stack.
 

> is that the major difference?
>

I think so, it makes goroutines cheap to create; only a few kb of initial 
stack, cheap to use; no trip through kernel space to save a lot of state, 
and trash TLB's and caches, and cheap to have many of them; in operation 
hundreds of thousands of goroutines in a busy server are the norm. This is 
also pretty much the case against threads.

Here is a presentation I gave at OSCON last year about all these 
things, https://dave.cheney.net/2015/08/08/performance-without-the-event-loop
 

>
>
> Den fredag 25 november 2016 kl. 17:34:24 UTC+1 skrev Ian Lance Taylor:
>>
>> On Fri, Nov 25, 2016 at 2:18 AM,  <roger...@gmail.com> wrote: 
>> > I have seen a lot of confusion on how go routines actually work 
>> internally. 
>> > Will the function execution ontop of the go routine be rewritten to a 
>> statemachine with continuations in the same way as the C# async await does? 
>>
>> I do not know how C# async await works.  That said, goroutines are not 
>> rewritten to state machines. 
>>
>>
>> > If I have only 1 OS thread and 1000 go routines, obviously there must 
>> be some sort of "magic" that makes it possible to multiplex these ontop of 
>> that thread. 
>> > How do the go routines store state so that they can continue from the 
>> last execution point when they resume execution? 
>>
>> A goroutine is basically a small stack.  All the goroutine state is 
>> saved on the stack.  To switch to a different goroutine, the goroutine 
>> scheduler changes the stack pointer.  On the new goroutine, it looks 
>> like the function call into the scheduler simply returns, and the 
>> goroutine continues running. 
>>
>> This is a standard programming technique known as a "coroutine".  For 
>> Go we used the name "goroutine" because 1) it is cute; 2) goroutines 
>> have functionality not available in most coroutine libraries, such as 
>> multiplexing across many OS threads and automatic use of epoll for 
>> network connections. 
>>
>>
>> > Is it safe to say that Go gives you the exact same support as the C# 
>> (and others) async await while still writing code that looks sequential? 
>>
>> I don't know C#.  goroutines let you write code that looks sequential 
>> because it actually is sequential. 
>>
>> Ian 
>>
>

-- 
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