8 ms·
24 days of Rust – Rayon
- pcwalton 10y agoRayon is definitely the best parallelism library I've ever used. We recently switched Servo over to using it for parallel restyling and layout and saw small gains in performance over our previous solution and drastic reduction in code complexity (and removed a whole pile of domain-specific unsafe code). Being able to switch .iter() to .par_iter() and have things "just work" is a game changer. The crucial thing about rayon is that sequential fallback is really fast, almost as fast as the sequential code you'd write anyway. This is important because, as paradoxical as it sounds, most CPU-bound programs work with small workloads most of the time, and so they don't want the overhead of parallelism for those cases. (It's the analogue of saving power by putting the CPU to sleep when it's not in use.) The occasional big workload that comes along is what you really want parallelism for, and the big trick is to handle that case without regressing the common sequential case. Rayon's work stealing approach based around scoped iterators is the ideal solution for this.
- deleted 10y ago[deleted]
- jMyles 10y ago> Rayon is definitely the best parallelism library I've ever used. Whenever people say this, I ask the following question in order to gauge whether I want to try the library in question: Have you used Twisted? Twisted is, to me, the quintessential example of a high-quality open source project. If you have used it extensively and still recommend Rayon, I'll give it a try.
- dbaupp 10y agoAssuming you're talking about the python library, it is more going for asynchronous IO and other more "concurrency" things than the data parallelism that rayon is designed for.
- steveklabnik 10y agoYeah, twisted is closer to tokio than rayon.
- jMyles 10y agoHey Steve. We met at TwilioCon 2011 - not sure if you remember that. How have you been? Is there a good guide for someone in my position? ie, to learn about tokio and rayon, having used python (for, in this case, concurrency and data science respectively)? Are you mostly using Rust these days?
- steveklabnik 10y agoOh hey! That was a very long time ago, but I loved TwilioCon. Things are good. I'm actually working on Rust full-time, so yeah, I use it a lot. :) I'm not sure there's a great guide yet, because a lot of this stuff is still shaking out. The Rust ecosystem in general is growing at a pretty steady clip, and new stuff pops up all the time: tokio is less than a year old, for example. There's two different kinds of problems here: "I found a library, what does it do?" and "What libraries exist?" In the former case, you're at the mercy of the library author to give you a good description. With the latter, one of the better ways is to drop by #rust on IRC, or post to users.rust-lang.org, asking for an overview of what exists. https://crates.io/search https://crates.io/search is also helpful. In this case, rayon is for "data parallelism", meaning "I have some data, I would like to do some work on it, and I'd like to make that paralell." Tokio is about asynchronous I/O.
- deleted 10y ago[deleted]
- pcwalton 10y agoTwisted is not for parallelism. Twisted is for concurrency.
- the8472 10y agoI have played around a tiny bit with par_iter over blocking IO tasks and seen some sched_yield() loops burning CPU time instead of backing off to futex_wait. That seems suboptimal and not exactly "the best ever" I'd expect from a parallelism library.
- pcwalton 10y agoThey should be doing that for a few iterations before backing off. Otherwise you end up with bad scheduling leading to slow warmups, among other problems. You shouldn't use rayon for blocking I/O; that's not what it's designed for. Rayon is a parallelism library, not a concurrency library.
- p0nce 10y ago> Being able to switch .iter() to .par_iter() and have things "just work" is a game changer. It's called .parallel() in D, works the same way I guess. It turns a lazy computation chain into a parallel one.
- Animats 10y agoThis is very nice. In Rust, if you accidentally share mutable data between threads, the borrow checker should catch it at compile time. Few other languages catch such errors. Go, for example, does not. This makes writing parallel code much, much safer.
- lukaslalinsky 10y agoI have not done any real programming in Rust, but whenever I see Rust code I'm amazed how different is it from Go, despite both having some shared use cases. Go's main selling point beyond concurrency is simplicity. And it's the simplicity that I like about it. On the other hand, it looks to me like Rust is turning into Scala.
- dikaiosune 10y agoMy personal experience with Rust (vs. Go and other languages) is that there is something really magical that all the sigils and syntactic complexity give you: once you've internalized Rust's approach it's ridiculously easy to build an accurate mental model of what's happening in almost any piece of code. From the high level constructs down to generated assembly, Rust produces the most predictable code I've ever written. While not the same kind of simplicity you're describing, my experience is that the value of Go's simplicity is to give you a low overhead mental model. While Rust has some complexity, I personally find it to have the lowest overhead mental model of anything I've worked with, due to its predictability, explicitness, and strong conventions. Granted, it definitely took some time for me to gain the experience necessary for this magic to occur. It's not really a "hack a quick thing together once every 10 years" kind of language. It's hard to convey this without getting you to actually learn Rust for a few days/weeks/months, but it's certainly been my experience and I hear it all the time from other Rust developers.
- kbenson 10y agoThe problem with people referring to more or less simple mental models, syntax, learning curves, expressiveness, etc is that they usually only focus on one of those at a time, when it requires multiple of them to get a good picture of how a language will work in practice for you, and in general. As an extremely simple example of this, compare BASIC and APL in terms of the learning curve. If we examine it in isolation, BASIC is obviously better. But if we use multiple criteria, the answer becomes much more nuanced, as we can see what the steeper learning curve allows. For a less extreme, but still ultimately the same comparison, imagine Perl and Python, or Go and Rust. A simple mental model is important, but if one choice is less simple, the question should really be what are you getting in return, and is the trade-off worth it? Otherwise, you should just program in BASIC and be done it it.
- ceronman 10y agoRayon seems very similar to Java 8 Parallel Streams or C# Parallel LinQ. What are the advantages/disadvantages of the Rust approach?
- dikaiosune 10y agoClosures in Rust are stack-allocated and LLVM can inline them and optimize them as if they're any regular imperative code, for one thing. This means that there's less overhead from managing the iterator chains, and that they're statically dispatched which saves on runtime indirection. The borrow checker also makes sure that you don't accidentally mutate non-thread-safe data from your parallel iterators.
- pjmlp 10y agoRegarding closures, that is also possible in Java and .NET, just you don't control when it might happen.
- Veedrac 10y agoIn Rust, each closure has a unique type, and derived expressions are templated on that type. This is key to making them statically dispatched, which is important for making the base case (sequential) fast.
- pcwalton 10y agoThe compiler guarantees no data races.