Transitioning to TBB 3.0

Moving your application from TBB 2.2 to TBB 3.0 should be painless.  We take backward compatibility seriously, and try to avoid breaking changes.  But occasionally we judge the benefit of a break to outweigh its costs.  For TBB 3.0, the breaking changes are few.  It’s unlikely you’ll run into trouble with them.

Breaking Changes

The breaking changes for TBB 3.0 are that the following methods of class task are changed to static methods:

    • spawn

    • destroy

    • allocate_additional_child_of



The changes are unlikely to break existing code, because these methods are almost always used in expressions such as “x.spawn(y)”, where x and y are expressions.  Though spawn is now a static method, the expressions x and y are still evaluated.  The only difference is that the value of expression x is no longer used by method spawn.

A source-level break occurs in code that takes the address of one of the changed methods.  For example:

     typedef void (task::*ptr)(task&);

     ptr p = &task::spawn;


Such code will now elicit an error message from the compiler. The edit below shows how to fix it:

     typedef void (task::*ptr)(task&);

     ptr p = &task::spawn;


Evolution motivated the change. The expression “x.spawn(y)” originally meant that task x spawns task y.  The task interface evolved in a way that made “x” unnecessary.  Starting from scratch, we would probably define “y.spawn()” to mean to “spawn y”.  Introducing that form now while retaining “x.spawn(y)” would make TBB confusing to existing users, and we did not want to break code using the old form.  

Making spawn static seems like a good compromise.  Old code still works and new code does not need to supply the superfluous x. The only drawback is that code sometimes must supply a class qualification, as in “task::spawn(y)”.  Our examples in the Tutorial needed no change on this point – the call was always in a context where the task:: prefix was implied.   In another blog, I’ll explain how we made old application binaries still work with the new library, even though the signatures have changed.  

The only other theoretically breaking change is that the functor parameters to “parallel_invoke” and “parallel_for_each” are now passed by const reference instead of by value.  We actually made this change in a TBB 2.2 update 2, and did so to be compatible with the corresponding PPL implementations. 

Deprecations

As a standards committee maven once said, deprecation is a “warning shot across the bow”.  It is a warning that a feature might disappear in the future.  So far nothing has disappeared in TBB, even 1.0 features.   I still recommend discontinuing use of deprecated features, because the features might disappear in the future.  A feature is usually deprecated because a better alternative exists. 

The features newly deprecated in TBB 3.0 are:

    • task::recycle_to_reexecute.  A call “t-> recycle_to_reexecute();” can be replaced with the sequence:
                t->set_ref_count(1);
      t->recycle_as_safe_continuation();

    • tbb::tbb_thread .  A use of tbb::tbb_thread can be replaced with TBB’s std::thread.



We did not remove the functionality of tbb_thread.  We renamed it std::thread, as in the C++0x draft.  It still has the same interface as the old tbb_thread.  It does not exactly match the C++0x specification, because doing so requires C++0x language features.  But it’s close enough for typical use cases.

We originally chose the name tbb::tbb_thread in TBB 2.1 to avoid name conflicts with vendor’s implementations of class std::thread, particularly in code that is not using namespace qualifiers.  It seemed like the right decision at the time.  But in TBB 3.0 we introduced many more C++0x features (e.g. condition_variable), where the tbb_ prefix was getting irksome. 

You get the TBB implementation of std::thread when you include tbb/compat/thread and TBB_IMPLEMENT_CPP0X=1. The default value of TBB_IMPLEMENT_CPP0X is 0 on platforms that implement std::thread. You can override our default definition to flip our implementation on or off.

Summary

Unless your code is using pointers to member functions of class tbb::task, your TBB 2.2 code should work just as well with TBB 3.0.

For more complete information about compiler optimizations, see our Optimization Notice.