Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Beginner
23 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
Highlighted
23 Views

Consider: C container; tbb::parallel_do(container.begin(), container.end(), [&]{ }); or tbb::parallel_do(container.begin(), container.end(), [&container]{ }); Jim Dempsey
0 Kudos
Highlighted
Beginner
23 Views

Yes, ok, the lambda were wrong, but the point is still valid.
0 Kudos
Highlighted
23 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
0 Kudos
Highlighted
Black Belt
23 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?
0 Kudos