4

Why do we need a deque for work-stealing? (e.g. in Cilk) The owner works on the top and the thief steals from the bottom. Why is it useful?

We might have multiple thieves stealing from the bottom. So, don't we need a lock anyway? I have read somewhere that larger jobs (for example created in a tree) are added to the bottom. So, stealing from bottom is more efficient (less communication, as the thieves become more busy by stealing them). Is that it?

towi_parallelism
  • 1,421
  • 1
  • 16
  • 38

3 Answers3

2

Work stealing actually really needs a deque. In the original paper, they have proved the maximum used memory on a system with P processors. The limit is given by the maximum size of any stack times the number of processors. That is actually only possible by following the busy leaves theorem. Also, another important feature of work stealing is that: When a worker does a spawn, it immediately saves the spawner on the deque and starts working on the child. For more information regarding their proofs, please read their original paper, in which they explain all I am saying. http://supertech.csail.mit.edu/papers/steal.pdf

Concurrency control in the work stealing deque accesses are not related to the work stealing scheduler, and in fact, much research has been made towards removing the locks from the deque (by using lock free structures) and also to minimize as much as possible memory barriers. For example in this paper (that i am sorry if can not access, but you can read the abstract anyways to get the idea): http://dl.acm.org/citation.cfm?id=1073974 the authors create a new deque for improving the afore mentioned aspects.

The steals are made from the side that the worker is not working on for possibly several reasons: Since the deque acts as a stack for each worker (the owner of the deque) the "bigger" jobs should be on top of it (as you can understand by reading the paper). When I say bigger I want to mean that those are probably the ones that will have more computation to do. Also, another important aspect is that by doing so (stealing from the deque owner's opposite work side) reduces the contention as in some new deque's both a victim and a thief may be working at the same time on the same deque.

guilhermemtr
  • 528
  • 1
  • 4
  • 15
  • Please tell me if you have any questions else, this is my research area so i am happy to help you in any way i can :) – guilhermemtr Apr 14 '15 at 19:30
  • 1
    Thanks guilhermemtr! This is absolutely true for fork-join models. For some models, a deque is not need, e.g. when you define all the tasks at compile time. That s how I see it. Let's have a discussion if you disagree.. – towi_parallelism Apr 17 '15 at 23:41
  • Well that is true. However please note that for models in which tasks are generated at runtime, using a deque (or any other data structure that allows to guarantee the busy leaves property (as discussed in the original paper)) is fulcral. So a queue can't be used (for example). – guilhermemtr Apr 18 '15 at 10:00
1

The details of the THE protocol are described in section 5 of "The Implementation of the Cilk-5 Multithreaded Language" which is available from MIT: http://supertech.csail.mit.edu/papers/cilk5.pdf

svick
  • 236,525
  • 50
  • 385
  • 514
1

You do not need a deque for work-stealing. It is possible (and people have done it) to use a concurrent data structure to store the pool of tasks. But the problem is that push/pop operations from workers and steal requests from thieves all have to be synchronized.

Since steals are expected to be relatively rare events, it is possible to design a data structure such that synchonization is performed mianly during steal attempts and even then when it is likely that there might be a conflict in popping an item from the data structure. This is exactly why deques were used in Cilk - to minimize synchronization. Workers treat their own deques as a stack, pushing and popping threads from the bottom, but treat the deque of another busy worker as a queue, stealing threads only from the top, whenever they have no local threads to execute. Since steal operation are synchronized, it is okay for multiple thieves to attempt to steal from the same victim.

Larger jobs being added to the bottom is common in divide-and-conquer style algorithms, but not all. There is a wide variety of strategies in place for what to do during stealing. Steal one task, few tasks, half the tasks, and so on. Each of these variants work well for some applications and not so well in others.

shams
  • 3,460
  • 24
  • 24
  • Thanks for your answer. I agree with most of it. Only the part "Since steals are expected to be relatively rare events": It is not true in a fork-join model. The whole model is based on stealing. Master worker creates the jobs and others steal almost all the time. right? – towi_parallelism Feb 01 '15 at 12:50
  • @TOWI_Parallelism, yes there are applications where steals will be comparatively more frequent. But, in many applications after the steal, a worker executing the task also spawns new tasks. These tasks get added to the local queue. So a worker does not need to steal from the master thread as often. – shams Feb 01 '15 at 17:16