Exemplo n.º 1
0
 task* execute() {
     if( root->node_count<1000 ) {
         *sum = SerialSumTree(root);
     } else {
         Value x, y;
         int count = 1; 
         tbb::task_list list;
         if( root->left ) {
             ++count;
             list.push_back( *new( allocate_child() ) SimpleSumTask(root->left,&x) );
         }
         if( root->right ) {
             ++count;
             list.push_back( *new( allocate_child() ) SimpleSumTask(root->right,&y) );
         }
         // Argument to set_ref_count is one more than size of the list,
         // because spawn_and_wait_for_all expects an augmented ref_count.
         set_ref_count(count);
         spawn_and_wait_for_all(list);
         *sum = root->value;
         if( root->left ) *sum += x;
         if( root->right ) *sum += y;
     }
     return NULL;
 }
 /*override*/ tbb::task* execute() {
     ASSERT( !(~LocalState->MyFlags & flags), NULL );
     if( n>=2 ) {
         set_ref_count(3);
         spawn(*new( allocate_child() ) FibTask(n-1,flags));
         spawn_and_wait_for_all(*new( allocate_child() ) FibTask(n-2,flags));
     }
     return NULL;
 }
	task* execute() {	//Overrieds virtual function task:: execute
		if( n<CutOff) {
			*sum = SerialFib(n);
		} 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
			spawn(b);
			//Start a and wait for children
			spawn_and_wait_for_all(a);
			//Do the sum
			*sum = x+y;
		}
		return NULL;
	}
Exemplo n.º 4
0
      tbb::task* execute () 
      {
	if (P_first_ > P_last_ || A_.empty())
	  return NULL;
	else if (P_first_ == P_last_)
	  {
	    execute_base_case ();
	    return NULL;
	  }
	else
	  {
	    // Recurse on two intervals: [P_first, P_mid] and [P_mid+1, P_last]
	    const size_t P_mid = (P_first_ + P_last_) / 2;
	    split_t A_split = 
	      partitioner_.split (A_, P_first_, P_mid, P_last_,
				  contiguous_cache_blocks_);
	    // The partitioner may decide that the current block A_
	    // has too few rows to be worth splitting.  In that case,
	    // A_split.second (the bottom block) will be empty.  We
	    // can deal with this by treating it as the base case.
	    if (A_split.second.empty() || A_split.second.nrows() == 0)
	      {
		execute_base_case ();
		return NULL;
	      }

	    double top_timing;
	    double top_min_timing = 0.0;
	    double top_max_timing = 0.0;
	    double bot_timing;
	    double bot_min_timing = 0.0;
	    double bot_max_timing = 0.0;

	    FactorTask& topTask = *new( allocate_child() )
	      FactorTask (P_first_, P_mid, A_split.first, A_top_ptr_, 
			  seq_outputs_, par_output_, seq_,
			  top_timing, top_min_timing, top_max_timing,
			  contiguous_cache_blocks_);
	    // After the task finishes, A_bot will be set to the topmost
	    // partition of A_split.second.  This will let us combine
	    // the two subproblems (using factor_pair()) after their
	    // tasks complete.
	    mat_view A_bot;
	    FactorTask& botTask = *new( allocate_child() )
	      FactorTask (P_mid+1, P_last_, A_split.second, &A_bot, 
			  seq_outputs_, par_output_, seq_,
			  bot_timing, bot_min_timing, bot_max_timing,
			  contiguous_cache_blocks_);
	    set_ref_count (3); // 3 children (2 + 1 for the wait)
	    spawn (topTask);
	    spawn_and_wait_for_all (botTask);
	    
	    // Combine the two results
	    factor_pair (P_first_, P_mid+1, *A_top_ptr_, A_bot);

	    top_min_timing = (top_min_timing == 0.0) ? top_timing : top_min_timing;
	    top_max_timing = (top_max_timing == 0.0) ? top_timing : top_max_timing;

	    bot_min_timing = (bot_min_timing == 0.0) ? bot_timing : bot_min_timing;
	    bot_max_timing = (bot_max_timing == 0.0) ? bot_timing : bot_max_timing;

	    min_seq_timing_ = std::min (top_min_timing, bot_min_timing);
	    max_seq_timing_ = std::min (top_max_timing, bot_max_timing);

	    return NULL;
	  }
      }