4 ms·
Go's goroutines as I understand are the same or very similar to Lua's coroutines and WinAPI's Fibers. Right? For the later two can calling C functions is cheap
by frik 12y ago
Go's goroutines as I understand are the same or very similar to Lua's coroutines and WinAPI's Fibers. Right?
For the later two can calling C functions is cheap. I would assume if you run Go with its default one thread option, it's cheap too. (Switching threads or even processes means context switching is what is usually expensive).
- unassuming_rat 12y agoNo, Go routines are not the same as coroutines in other languages. In order to provide efficient lightweight threads, Go allocates only a small amount of memory for each stack, growing it as function calls require it by appending another segment in a linked list. This makes thread creation very cheap. The problem with segmented stacks is that they can cause "stack thrashing." Suppose a goroutine is right at the boundary between two stacks. It calls a function that exhausts the available segment, forcing the allocation of a new segment, which is then added to the linked list. The function runs, and then frees the segment upon return. If this boundary happens to fall within a tight loop, you'll see a severe drop in performance, to the point that it's completely unacceptable. Recognizing this, Go relatively recently switched away from segmented stacks. It now uses a strategy called relocatable stacks, or contiguous stacks. See https://docs.google.com/document/d/1wAaf1rYoM4S4gtnPh0zOlGzWtrZFQ5suE8qr2sD8uWQ/pub https://docs.google.com/document/d/1wAaf1rYoM4S4gtnPh0zOlGzW... for details. Similar concerns prompted Rust to move away from segmented stacks, but as relocatable stacks require a garbage collector that was not a viable way forward for Rust, so it just dropped the idea completely. The problem with both approaches is that C has no knowledge or support of either segmented or relocatable stacks. This means that calling out to C in Go involves a completely different calling convention that involves switching to a larger stack, running there, and then switching back--which is very expensive, especially compared to languages like Lua where the C FFI is basically free. That's why Go reimplements glibc by performing its own system calls--to avoid the C FFI. In conclusion, every language feature--no matter how enticing--has a cost.