user3017335
user3017335

Reputation: 285

general tbb issue for calculating fibonacci numbers

I came across the tbb template below as an example of task-based programming for calculating the sum of fibonacci numbers in c++. But when I run it I get a value of 1717986912 which can't be the case. The output should be 3. What am I doing wrong?

  class FibTask: public task 
  {
public:
const long n;
long * const sum;
FibTask( long n_, long* sum_ ) : n(n_), sum(sum_) {}

    task* execute( )
    { 
        // Overrides virtual function task::execute
    if( n < 0) 
    {
        return 0;
    } 
    else 
    {
        long x, y;
        FibTask& a = *new( allocate_child( ) ) FibTask(n-1,&x);
        FibTask& b = *new( allocate_child( ) ) FibTask(n-2,&y);
        // Set ref_count to "two children plus one for the wait".
        set_ref_count(3);
        // Start b running.
        spawn( b );
        // Start a running and wait for all children (a and b).
        spawn_and_wait_for_all( a );
        // Do the sum
        *sum = x+y;
    }
        return NULL;
}

long ParallelFib( long n ) 
{
    long sum;
    FibTask& a = *new(task::allocate_root( )) FibTask(n,&sum);
    task::spawn_root_and_wait(a);
    return sum;
}
  };



    long main(int argc, char** argv)
{
    FibTask * obj = new FibTask(3,0);
    long b = obj->ParallelFib(3);
    std::cout << b;
    return 0;
 }

Upvotes: 0

Views: 318

Answers (1)

Anton
Anton

Reputation: 6577

The cutoff is messed here. It must be 2 at least. E.g.:

if( n<2 ) {
    *sum = n;
    return NULL;
}

The original example also uses SerialFib as showed here http://www.threadingbuildingblocks.org/docs/help/tbb_userguide/Simple_Example_Fibonacci_Numbers.htm

The inefficient method for calculating Fibonacci numbers using inefficient blocking style technique will be even more inefficient without call to SerialFib().

WARNING: Please note that this example is intended just to demonstrate this particular low-level TBB API and this particular way of using it. It is not intended for reuse unless you are really sure why you are doing this.

Modern high-level API (though, still for the inefficient Fibonacci algorithm) would look like this:

int Fib(int n) {
    if( n<CUTOFF ) { // 2 is minimum
        return fibSerial(n);
    } else {
        int x, y;
        tbb::parallel_invoke([&]{x=Fib(n-1);}, [&]{y=Fib(n-2);});
        return x+y;
    }
}

Upvotes: 1

Related Questions