0

While I'm learning cilk, I countered with 2 opposite examples:

  1. From intel

  2. from wiki (or other examples in the net):

The oppposite lies on those 2 lines:

x = spawn fib (n-1);
y = spawn fib (n-2);

The first site says:

You do not need to add a cilk_spawn attribute to the second recursive call to fib() because that will create an empty continuation

  1. I dont understand why?
  2. What is the right way? (using 2 spawn commands or just one ? )
4

2 回答 2

3

The code from intel document "int x = cilk_spawn fib(n-1);" asks for permission to run it in another threat, while the next line of "int y = fib(n-2);" will be run on the same threat as the main program. The wiki code asks for a new threat also for computing fib(n-2) so that if there are more than three processors to run the main progran (fib(n)), fib (n-1) and fib(n-2) all on seperate threats.

Both codes will perform the same if there were only two processors. The following is from the wiki page:

... A processor is not obligated to assign a spawned procedure elsewhere; if the machine only has two processors and the second is still busy on fib(1) when the processor executing fib(2) gets to the procedure call, the first processor will suspend fib(2) and execute fib(0) itself, as it would if it were the only processor. Of course, if another processor is available, then it will be called into service, and all three processors would be executing separate frames simultaneously.

于 2015-05-30T09:02:47.683 回答
1

The example in Wikipedia that you're referring to is from MIT Cilk, which required that all calls to Cilk functions be spawned. That requirement was removed by Cilk++, which evolved into Intel's Cilk Plus implementation.

Keep in mind that it's the continuation that's stolen, not the spawned function. The worker that executes the code before the spawned function will execute the spawned function. The cilk_spawnpushes the continuation onto the worker's deque, making it available for stealing by an idle worker.

Consider the full implementation of fib in Cilk Plus:

int fib(int n) {
    if (n < 2)
        return n;
    int x = cilk_spawn fib(n-1);
    int y = fib(n-2);
    cilk_sync;
    return x+y;
}

If you put a cilk_spawn on the second recursive call to fib, then you're allowing an idle worker to steal the continuation after that call. But that strand immediately ends at the cilk_sync, so it's a waste of time.

于 2015-05-31T19:17:10.663 回答