4 ms·
The fact that this is all on one cpu seems like a problem, does it not? Does someone have a mental model of how to take advantage of multiple cpus without crea
by luckydude 9y ago
The fact that this is all on one cpu seems like a problem, does it not?
Does someone have a mental model of how to take advantage of multiple cpus without creating a mess? If so, can you explain it like I'm 5 (or more like I'm 55 and tired)?
- Kenji 9y agoYes. Either use threadsafe queues/ringbuffers to transfer data between threads. Or triple-buffer it and swap buffers in a threadsafe manner. Those are the best approaches. Don't start a thread per work item. Start worker threads and distribute work among them. Never ever block a GUI thread. Always know which thread works on which data structures and don't even make more variables accessible in your worker threads. Keep the variables multiple threads can access to an absolute minimum and make sure access is always protected by a mutex. If you repect these rules, threading is safe and fun.
- rumcajz 9y agoI think the environment is a bit different now than it was once. You typically have a cluster of machines, so you have to be able to run multiple instances of your application simultaneously to use all the processing power. And once you can run mutliple instances of the application in parallel you can as well run 16 instances of it on a 16-core box. The upside is that you don't have two levels of granularity (threads, machines) but only a single one (processes) which makes both the coding and the ops as well as stuff like capacity planning much easier.
- aidenn0 9y agoEven absent the cluster of machines I found this to be very useful. Several years ago, I would use zeromq (thank you, btw) for communication and if the socket overhead was found to be an issue, I would merge two processes and switch from tcp:// to inproc://. Many "corrupt the world" type bugs are isolated from each other by processes, and it made it very hard to accidentally share state (the file system of course is a giant hunk of share state, but you very rarely accidentally write to a file).
- aidenn0 9y agoMessage passing without mutable shared state seems to be the least messy way. There are a lot of useful concurrent patterns that can be represented this way, and it is much more tractable than having to manage mutual exclusion manually. Now different tools work differently for this. If you use multiprocessing, then you have no implicit shared state (you can use the filesystem or shm &c. to share state, but not much is shared by default). Clojure e.g. defaults to no mutability, so you can share state safely by default. That covers concurrency. For parallelism, there are some useful structures to. In Common Lisp, I usually write a program single-threaded, then I profile, and add use lparallel[1] to parallelize the slow part. 99% of the time the slow part is a loop, so making it parallel is fairly straightforward. If it's a series of possibly interdependent calculations, then the calculations can usually be represented as a tree, and lparallel has a tool for that as well. There is absolutely nothing lisp-specific in lparallel, any language with first-class functions and some form of thread-local variables could implement all that it does. It's not a silver bullet but it does solve the "My cores stopped getting faster, but I have more cores now" problem about 80% of the time. 1: https://lparallel.org/ https://lparallel.org/
- imtringued 9y agoProbably because people get taught how to use low level primitives like mutexes and then proceed to have shared mutable state (aka two threads write to one memory location). For the vast majority of applications the complexity of shared mutable state isn't worth it. They should instead restrict themselves to only having one thread per memory location that is allowed to write to it. For 99% of applications that means you take your favourite threadsafe queue implementation for your specific language and launch threads and only communicate this way. The messages should preferably be immutable, copies or at the very least marked readonly via const if copying is too expensive. I'd recommend you to take a look at Erlang. Also remember that there is no magic pixie dust. Functional programming languages are not inherently better than non functional programming languages at concurrency and parallelism. They merely leverage the "no multiple writer" principle by default. Immutable data is threadsafe primarily because it's guaranteed that there is only a single writer.