I've look at a paper called A Primer on Scheduling Fork-Join Parallelism with Work Stealing. I want to implement continuation stealing, where the rest of the code after calling spawn
is eligible to be stolen. Here's the code from the paper.
1 e();
2 spawn f();
3 g();
4 sync;
5 h();
An import design choice is which branch to offer to thief threads. Using Figure 1, the choices are:
Child Stealing:
- f() is made available to thief threads.
- The thread that executed e() executes g().
Continuation Stealing:
- Also called “parent stealing”.
- The thread that executed e() executes f().
- The continuation (which will next call g()) becomes available to thief threads.
I hear that saving a continuation requires saving both sets of registers (volatile/non-volatile/FPU). In the fiber implementation I did, I ended up implementing child stealing. I read about the (theoretical) negatives of child stealing (unbounded number of runnable tasks, see the paper for more info), so I want to use continuations instead.
I'm thinking of two functions, shift
and reset
, where reset
delimits the current continuation, and shift
reifies the current continuation. Is what I'm asking even plausible in a C environment?
EDIT: I'm thinking of making reset
save return address / NV GPRs for the current function call (= line 3), and making shift
transfer control to the next continuation after returning a value to the caller of reset
.