How it works...

rayon::join is pretty simple. It takes two closures, potentially runs them in parallel, and returns their returned values in a tuple [25]. Wait a second, did we just say potentially? Isn't it always better to run things in parallel?

Nope, at least not always. Sure, if you really care about things running together at all times without blocking, say a GUI and its underlying I/O where you definitely don't want the mouse cursor to freeze when opening a file, you always need to have all processes running in their own thread. But most applications for concurrency don't have this requirement. A big part of what makes concurrency so important is its ability to run code that would normally run sequentially (that is, one line after another) in parallel if required. Notice the choice of words here—code that would normally run sequentially. These kinds of algorithms do not inherently need concurrency, but they might get a boost out of it. Now comes the potential part—firing up a thread might not be worth it.

To understand why, let's look at the hardware side of things. We are not going to dive too deep into this territory because:

a) the fact that you're reading this book makes me think you're more of a software person and b) the exact mechanisms of CPUs tend to change very rapidly nowadays and we don't want the information provided here to be outdated in a year.

Your CPU divides its work among its cores. A core is the basic computation unit of the CPU. If the device you're reading this on is not made out of paper and younger than two decades, it most probably contains multiple cores. These kinds of cores are called physical and can work on different things at the same time. A physical core itself also has ways to perform multiple jobs. Some can divide themselves into multiple logical cores, splitting work further. For example, an Intel CPU can use hyper-threading, which means that if a program only uses the integer addition unit of a physical core, a virtual core might start working on the floating points addition unit for another program until the first one is done.

If you don't care about the available amount of cores and simply start new threads without limit, the operating system will start creating threads that don't actually run concurrently, because it ran out of cores. In this case, it will perform context switching, which means that it stores the current state of the thread, pauses it, works on another thread for a split second, and then resumes the thread again. As you can imagine, this costs quite some resources.

This is why if it's not vital to run two things in parallel, you should first check if there are any cores idle (that is, available) in the first place. Because rayon::join does this check for you; among other things, it will only run the two closures in parallel if it's actually worth it to do so. If you need to do this work yourself, check out the num_cpus crate (https://crates.io/crates/num_cpus).

By the way, the parallel iterators from the last recipe go even further: If the amount of elements and work in them is so small that it would cost more to initiate a new thread for them than to run it sequentially, they will automatically forego concurrency for you.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.149.236.27