- Many graph algorithms use a queue or a stack, to store partial paths to be extended further. Some version of DFS hide the stack in the call stack.
Many graph algorithms use a queue or a stack, to store partial paths to be extended further. Some version of DFS hide the stack in the call stack.
If there is a queue based version of the algorithm use it: Without queue, it's more difficult to share work, and you need to find other ways to apply the following tricks.
If there is a queue based version of the algorithm use it: Without queue, it's more difficult to share work, and you need to find other ways to apply the following tricks. - The trick for easy parallelization is to distribute queued elements for being processed by available processing nodes. So instead of extending the explored path one edge at a time, you'd extend N nodes in the same time in parrallel. Using queues to distribute work is the easiest way to parllelize work: one process manages the queue, and N worker-processes that dequeue the the elements, process them and enqueue the results.
The trick for easy parallelization is to distribute queued elements for being processed by available processing nodes. So instead of extending the explored path one edge at a time, you'd extend N nodes in the same time in parrallel. Using queues to distribute work is the easiest way to parllelize work: one process manages the queue, and N worker-processes dequeue the elements, process them and enqueue the results.
- Most graph traversal algorithms are inherently sequential. Parallelizing them means that you might process elements in the queue that would never be processed in the sequential version. So there is a tradeoff to find between adding processing nodes (with the risk of doing unnecessary work) and having less nodes (but going back to sequential like performance).
Most graph traversal algorithms are inherently sequential. Parallelizing them means that you might aggressively process elements in the queue that would never be processed in the sequential version. So there is a tradeoff to find between adding more workers (with the risk of doing unnecessary work) and having less workers (but going back to sequential like performance).
So be prepared to make measurements and validate your approach.
A long time ago, I had for example to paralelizeparallelize A* on a limited set of geographical data. Measurements showed that adding up to 4 nodesworker-nodes increased performance, but beyond 4, the performance decreased again, just because of the additional communication overhead and the unnecessary extension of unpromising partial paths.
- First, building your MST already requires you to explore every node
- Second, graph exploration algorithms have to unfold node by node and edge by edge.
When you start at the orange node, you don't know how many branches there will be in the MST nor which part of the graph to assign to which processorworker.
With the approach proposed above, you'd enqueue the first node (orange 8 ). A free processworker dequeues it, prolonges the path and enqueue the single result (O8->8). As we are in a "corridor", the same must happen again (O8->8->8) before we have more choices and more parallelism. then Then a free processworker-process dequeues the only path in the queue, extends it: we have 2 alternatives that will be enqueued: O8->8->8->6 and 08->8->8->2. Now a first processorworker will take the first path in the queue (...->6), another free processorworker will take the second path (...->2), and both processorsworkers extend in parallel their nodes. If both processesworkers have the same speed, we now have 5 pathpaths in the queuqueue and uptup to 5 processorsworkers busy, and so on.
Of course, you'll notice that O8->8->8->6->bottom2 and O8->8->8->2 arrive at the same point. In your exploration you must avoid such duplicates. This can be done by marking visited nodes to avoid double visit. This cannot be done safely in the processorsworkers because of synchronisation issues. So you may implement this when you enqueue the results and discard any path that arrives at an already visited node.
With this approach, everytime there's a branch, you'll use more pralelism until you reach the maximum processorsnumber of workers. However in your simple graph, I think that you'll never have more than 5 processorsworkers active at the same time , that 'sthat's 6 parallel processes if you add the queue manager.
THereThere are any other parallelization of task possible, without adding workers, for example parrallelizing the sorting of the queue, filtering out the filtering of doubled targets, etc...
If your graph topology is a bottleneck for parallization, you may introduce some randomness. Take K random nodes and start exploration from there,there; when enqueingenqueuing in the global queue, any path with nodes in common would be merged. As soon as onone of the processor gets iddle, pick a new random unvisited node and add it to the queue.
This variant adds a small inefficiency: some nodes might get visited twice, once from each connection. It's those that lead to a path merger. But it keeps all the processors as much busy as possible. In your example, most of the time 8 processors will work instead of a maximum of 5 before.
And this is why in my original answer, I adviced to carefully measure performance, to find teh postthe most suitable parallizationparallelization strategy (which might also depend on the graph topology).