7 ms·
> I don't want M:N threading as Go implements it. As someone who writes code for enterpricey businesses doing a lot of I/O bound stuff, golang style M:N thread
by sebcat 10y ago
> I don't want M:N threading as Go implements it.
As someone who writes code for enterpricey businesses doing a lot of I/O bound stuff, golang style M:N threading is a godsend over Java's standard library, and other common platforms in that space. Being able to express your code in a sequential manor and still gain the performance offered by implicit fiber,goroutine,w/e scheduling is pretty awesome. With futures, there's still some language semantic overhead from the point of view of the developer.
In my problem space, M:N threading is simply worth it. And if I need anything better performing, I can still switch to C for specific use cases.
- steveklabnik 10y agoWell, one of the problems with M:N threading is that the "switch into C for that part" gets a lot more expensive, negating the speed increase.
- pcwalton 10y ago> Being able to express your code in a sequential manor and still gain the performance offered by implicit fiber,goroutine,w/e scheduling is pretty awesome. You don't gain as much performance. On Linux, you don't actually gain that much if anything over 1:1 threading. Most of the benefits of goroutines actually comes from the small stacks, which don't have anything to do with M:N and 1:1 to begin with—they're a feature of GC. As the blog post states, our end goal is to achieve the ergonomics of Go-style M:N without sacrificing nginx levels of performance. With this futures library, we've established the foundations. It would make no sense to give up before even trying. > And if I need anything better performing, I can still switch to C for specific use cases. Why would you write networking code in C in 2016, when there are better alternatives available (like this one)? Rust's philosophy is to have both performance and ergonomics. It rejects the idea that optimal performance requires a cumbersome programming model. I'm not about to give up on that.
- derefr 10y ago> On Linux, you don't actually gain that much if anything over 1:1 threading. You use green threads instead of native threads because native threads have space overhead, not because they have time overhead. Attempting to spawn 100k OS threads will do strange things to most kernel scheduling algorithms; they're not optimized for that use-case.
- pcwalton 10y ago> You use green threads instead of native threads because native threads have space overhead, not because they have time overhead. The main overhead of a thread, green or native, is the stack. The size of the stack is independent of whether you use native or green threads. Go's small stacks are actually made possible by its GC, not its choice of 1:1 or M:N. In musl, for example, you can have 2KB stacks [1] with 1:1. I haven't seen a benchmark of huge numbers of native threads vs. a userland scheduler, but I have a hard time imagining that a userland scheduler will beat the kernel's scheduler. The kernel scheduler has a much more global picture of the system compared to userland. [1]: https://github.com/rofl0r/musl/blob/d05aaedaabd4f5472c233dbbd1ff4bb9c9c99794/include/limits.h#L64 https://github.com/rofl0r/musl/blob/d05aaedaabd4f5472c233dbb...
- derefr 10y ago> The kernel scheduler has a much more global picture of the system compared to userland. In most of the comparisons I've seen (usually for Erlang), worst-case latency was the important factor, so interaction with the kernel scheduler was avoided as much as possible. In the Erlang runtime, you can pass a switch to cause the userland scheduler-threads to each get bound to a particular processor core, and to cause the kernel scheduler to avoid scheduling anything on those cores. Effectively, this partitions the processor into a set of cores the OS scheduler entirely manages, and a set of cores that the userland scheduler entirely manages.
- eridius 10y agoIf the kernel scheduler completely hands control of the core over to the program, doesn't that mean you can only run one or two programs on the entire machine at once without running out of cores? Surely the kernel still schedules other threads on that core too.
- derefr 10y agoYes, that's rather the point: we're talking about highly-multicore server machines (e.g. 16/32 cores, or perhaps far more) entirely dedicated to running your extremely-concurrent application. You want all but one or two of those cores just running the app and nothing else. You leave one or two cores for the "control plane" or "supervisor"—the OS—to schedule all the rest of its tasks on. It's a lot like a machine running a hypervisor with a single VM on it set to consume 100% of available resources—but actually slightly more efficient than that, since a guest can intelligently pin allocate cores to itself and pin its scheduler-threads to them and then just stop thinking about the pinning, while a hypervisor-host is stuck constantly thinking about whether its vCPUs-to-pCPU mapping is currently optimal, with what's basically a black box consuming those vCPUs.
- lightcatcher 10y ago> Why would you write networking code in C in 2016, when there are better alternatives available (like this one)? Support for kernel bypass networking libraries like ibverbs, DPDK (has an old unmaintained Rust wrapper) and other IO kernel bypass libraries such as SPDK and IOAT. If Rust supported these libraries, I'd much prefer the future based Rust code to a massive event loop in C.
- bluejekyll 10y agoIt's all open-source, this is an area that if it matters this much to you, you could help support. The Rust community is hugely welcoming to people coming on and helping.
- JoshTriplett 10y agoThe article mentioned that the authors would love to help make futures-based wrappers for C libraries. You might ask if they could help with wrappers for ibverbs, DPDK, SPDK, and IOAT.
- benlwalker 10y agoI'm one of the authors of SPDK (which includes an NVMe driver and an IOAT driver). If the community wants to add rust bindings to those two components I'd be very supportive.
- gravypod 10y ago> Why would you write networking code in C in 2016, when there are better alternatives available (like this one)? As someone who's done a bit of game development in the past I can easily say that you'll fall flat on your face in some fields if you don't write your own protocols. There are simply no protocols that operate well in every use case and there are also use-cases without standardized protocols. For extremely high performance operations you NEED to use a custom protocol in some case to squeeze every bit of power out of your applications. From a game development perspective you need to handle two types of content: content that isn't really ordered by time occurrence and content that needs to happen sequentially. Because of this you can correctly optimize your networking stack for those needs and get your networking system really fast. Some people have taken to using TCP with a JSON message passing system and that just doesn't work large scale. You'll have huge latency issues and with a big enough game you have to do some serious bit-packing to make it cost effective to host servers for. Now I'm speaking generally and this is just from my experience but there is definitely still a reason to write your own network code.
- kibwen 10y agoI believe pcwalton agrees that the ability to write one's own networking code is important. The quoted line is simply questioning why you'd write such code in C (which, if you're a game developer, means that "platform support" is a perfectly valid answer).
- pcwalton 10y agoSure, there are valid reasons to write your own network code. The question is whether you should write it in C. :)
- apendleton 10y ago> In my problem space, M:N threading is simply worth it. And if I need anything better performing, I can still switch to C for specific use cases. It maybe sounds like you should just use Go, which (as you point out) makes exactly those tradeoffs. I think Rust is aiming for a different market segment, with customers that want to make a different set of tradeoffs. Seems ideal to have both options. In particular, I don't think switching to C will ever be something Rust will want to require of its users.
- serge2k 10y ago> I can still switch to C for specific use cases. So use go and switch to rust for specific use cases.