Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Stefano_P_
Beginner
93 Views

parallel_do requires copiable items, and parallel_for_each inherits this limitation

Hi,

suppose we have a container C of objects T, C<T> and T is non-copiable, deriving from boost::noncopiable, and some tbb::parallel_do calls:

[cpp]

C<T> container;

tbb::parallel_do(container.begin(), container.end(), ...);

[/cpp]

or suppose we have an abstract base class B:

[cpp]

boost::ptr_vector<B> container;

tbb::parallel_do(container.begin(), container.end(), ...);

[/cpp]

These don't compile as Item, so T or B, is copied in do_iteration_task, there is an "Item my_value". It should be "Item& my_value" but I understand this violates the whole design, as you can feed objects to a tbb::parallel_do while it's still running so objects must (?) be part of internal tasks. I'm not a big fan of that but fine, even if I haven't spotted this limitation in any documentation.

BUT this doesn't justify tbb::parallel_for_each to fail. It's currently implemented using tbb::parallel_do that has this constraint, so you cannot use it with non-copiable items or complex containers like boost::ptr_* BUT tbb::parallel_for_each doesn't need to copy object.

Can we have it reimplemented in terms of tbb::parallel_for? Or possibly have the limitation in tbb::parallel_do removed?

At affects al least any TBB version <= 4.1.

Thank you.

Stefano

0 Kudos
4 Replies
jimdempseyatthecove
Black Belt
93 Views

Consider: C container; tbb::parallel_do(container.begin(), container.end(), [&]{ }); or tbb::parallel_do(container.begin(), container.end(), [&container]{ }); Jim Dempsey
Stefano_P_
Beginner
93 Views

Yes, ok, the lambda were wrong, but the point is still valid.
jimdempseyatthecove
Black Belt
93 Views

Don't pass the container entries by value, pass by reference or pointer, or {container reference/pointer and index}. If you do not want copy operators (or can't have), then do not use a syntax that requires a copy operator. Jim Dempsey
RafSchietekat
Black Belt
93 Views

The problem with the proposed solution would be that parallel_for implies random iteration and parallel_for_each implies input iteration, which does not require the iterators' referents to persist beyond reference incrementation, so even without feeder functionality a copy is required to achieve parallelism. Perhaps template specialisation magic could save the day (tell me if I should have had a coffee first), but that can get complicated to implement and maintain and would muddle the situation, so why not instead make the intention clear by using parallel_for directly?
Reply