4 ms·
My impression is that what kind of parallelism patterns you need is pretty consistent within entire fields of programming. So you can go an entire career of per
by trishume 6y ago
My impression is that what kind of parallelism patterns you need is pretty consistent within entire fields of programming. So you can go an entire career of performance optimization within HPC, game dev, film rendering or trading systems and never use the patterns the others say they use all the time.
My experience with process-based parallelism is that yes on Linux it's basically isomorphic to thread-based parallelism. It's just so much more code to do the same thing.
In Rust adding a new special-purpose background thread with some standard-library channels is 30 lines of code and I can probably even access the same logging system from the other thread.
If I wanted to do that with processes I need to:
- Coordinate a shared memory file over command line arguments or make sure everything is fork-safe
- Find a library for shared-memory queues
- Deal with making sure that if either process crashes the other process goes down with it in a reasonable way.
- Make sure all my monitoring/logging is also hooked up to the other process.
If I want to use a shared memory data-structure with atomics I need to either not use pointers or live dangerously and try and memory-map it at the exact same offsets in each process and ensure I use a special allocator for things in the shared file.
Yes you can do all the same things with both approaches, I just find threads take way less code. It's not too bad if all your processes are doing the same thing, and you also need to scale to many servers anyhow. It's more annoying if you want to have a bunch of different types of special background processes.
- amboar 6y agoI realise your post is an argument in favour of Rust over C for these things, but regardless, you might be interested in a WIP library I've started to solve most of the issues you outlined: https://github.com/amboar/shmapper#libshmap https://github.com/amboar/shmapper#libshmap
- jez 6y ago> In Rust adding a new special-purpose background thread with some standard-library channels is 30 lines of code and I can probably even access the same logging system from the other thread. Do you happen to have a link to code that does this? This sounds similar to a problem I have right now and I’d love to see what solution you’ve arrived at.
- malkia 6y agoThe bigger issue is coordinating these threads ("workers") with threads from other processes, there is nothing on Windows and Linux to do so, then again I haven't had much experience with Grand Dispatch (OSX) to know if it's worth. Windows has new thread pool API, but even TBB or ConCRT do not use it. (though the new par-support in STL (msvc) does).
- johncolanduoni 6y agoWindows, Linux and macOS all have inter-process mutexes and condition-variable-ish constructions. Windows has named mutex, semaphores, and events that can be opened by multiple processes, and the pthread API supports mutex and condition variables in shared memory. Linux additionally supports its futex primitive in shared memory regions (which is how the pthread API is implemented on that OS).
- malkia 6y agoThanks! Wasn't aware of this possible use, and havent' used much explicitly named pipes/mailslot except for direct communication. Wondering how would still work - I mean something ought to be the "task manager" in all that, coordinating. Why else come up with this - https://docs.microsoft.com/en-us/windows/win32/procthread/thread-pools https://docs.microsoft.com/en-us/windows/win32/procthread/th...?
- sgtnoodle 6y agoWhen you have built in support for threads in a language, it definitely makes sense that it would be easier to use than operating system mechanisms. For a lot of the non-embedded code that I end up writing, though, there's usually an inherent benefit to using processes over threads. It usually comes down to the benefits of having separate memory spaces. You can safely use code that was never written to be thread-safe, saving time otherwise spent refactoring gnarly old code. Also, it makes it a lot easier to mix and match different languages. For python in particular, it avoids having to battle for the global interpreter lock. I think what's nice about rust is that, because it makes it difficult to write thread-unsafe code, it's naturally easier to add threading at some point in the future without too much pain. As a result, more applications can benefit from having access to multiple CPU cores. I don't think that's quite the same thing as pure performance per watt, though. That really comes down to how the code was written, and how well the compiler can optimize it. Rust may have some advantages there over C, since it constrains what you can do so much that the compiler has a smaller state space to optimize over. Someone who knows what they're doing in C, though, could likely write very efficient code that effectively uses parallelism, and may gain an edge over rust simply by cleverly leveraging the relative lack of training wheels. For high performance compute, rust vs. C may be a wash. For consumer facing applications, though, the more programs that can use multiple cores to run faster (even if less efficiently), the better.