"When problems resist parallelization or have no appreciable latency to hide, the third way that concurrent execution can improve performance is to increase the throughput of the system. Instead of using parallel logic to make a single operation faster, one can employ multiple concurrent executions of sequential logic to accommodate more simultaneous work. Importantly, a system using concurrency to increase throughput need not consist exclusively (or even largely) of multithreaded code. Rather, those components of the system that share no state can be left entirely sequential, with the system executing multiple instances of these components concurrently. The sharing in the system can then be offloaded to components explicitly designed around parallel execution on shared state, which can ideally be reduced to those elements already known to operate well in concurrent environments: the database and/or the operating system."
Even if you can't use the database or os and still want to get "multiple concurrent executions of sequential logic" then just use a message queue. That's what Go provides, what blocking queues in java provide, what most actor based systems provide (e.g. Akka, Dart), what unix pipes provide and what all kinds of inter process messaging systems provide. Most of your code can as impure, sequential and lock free as it always was. You only have to make your messages immutable.
And that's why I love Node.js: the single-threaded concurrency (or should I say non-concurrency?) is built-in in the execution model. Building your architecture decoupled from the ground up is useful, and Node.js does a great job at it.
I found Redis is an awesome middleware for MQ purposes. Its builtin PubSub system, blocking POPs and amazing speed make it a perfect fit.
But beware: it's easy to get it wrong and make the system a tangled mess of messages. Just make sure the message dispatch overhead is worth it.
My last 15 years of practice indicate that other approaches lead to unnecessary complication, and are less likely to be effective (threads and semaphores in particular.)
[+] [-] discreteevent|13 years ago|reply
"When problems resist parallelization or have no appreciable latency to hide, the third way that concurrent execution can improve performance is to increase the throughput of the system. Instead of using parallel logic to make a single operation faster, one can employ multiple concurrent executions of sequential logic to accommodate more simultaneous work. Importantly, a system using concurrency to increase throughput need not consist exclusively (or even largely) of multithreaded code. Rather, those components of the system that share no state can be left entirely sequential, with the system executing multiple instances of these components concurrently. The sharing in the system can then be offloaded to components explicitly designed around parallel execution on shared state, which can ideally be reduced to those elements already known to operate well in concurrent environments: the database and/or the operating system."
Even if you can't use the database or os and still want to get "multiple concurrent executions of sequential logic" then just use a message queue. That's what Go provides, what blocking queues in java provide, what most actor based systems provide (e.g. Akka, Dart), what unix pipes provide and what all kinds of inter process messaging systems provide. Most of your code can as impure, sequential and lock free as it always was. You only have to make your messages immutable.
[+] [-] kaoD|13 years ago|reply
I found Redis is an awesome middleware for MQ purposes. Its builtin PubSub system, blocking POPs and amazing speed make it a perfect fit.
But beware: it's easy to get it wrong and make the system a tangled mess of messages. Just make sure the message dispatch overhead is worth it.
[+] [-] miga|13 years ago|reply
This solution is quickest to debug, and most efficient. One can also use multiprocessing-like approach: http://docs.python.org/2/library/multiprocessing.html
My last 15 years of practice indicate that other approaches lead to unnecessary complication, and are less likely to be effective (threads and semaphores in particular.)
[+] [-] JoeAltmaier|13 years ago|reply
Message passing is a reasonable approach. Its particularly simple to design, and deadlock-free if message processors don't block on further messages.
Drawbacks: Simplest when each message class (or queue) has one thread to handle it. But that doesn't optimize for available hyperthreads.
[+] [-] benwen|13 years ago|reply