Reputation: 21
I have a single loop which I want to parallelize. The loop implies doing the following:
std::vector<int> input = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
std::vector<int> output;
for(size_t i(0); i < input.size(); ++i)
{
output.emplace_back(input[i] * 2);
}
However, I would like to preserve the order in the output. I tried to use tbb::enumerable_thread_specific to do that:
tbb::enumerable_thread_specific<std::vector<int>> threadData;
tbb::parallel_for(size_t{0}, input.size(), [&](size_t i)
{
auto& local = threadData.local();
local.emplace_back(2 * input[i]);
});
for (const auto& local : threadData)
{
output.insert(output.begin() + output.size(), local.begin(), local.end());
}
However, the order is not preserved. I also tried to specify the partitioner:
tbb::static_partitioner()
but it didn't help as well.
What is the correct way to parallelize a for loop while preserving the order in the output?
Upvotes: 2
Views: 860
Reputation: 50836
Doing a task in parallel while preserving a given order is generally hard (and not always possible) since it often means some things should be done sequentially.
Here you can easily solve this thanks to direct indexing:
std::vector<int> input = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
std::vector<int> output(input.size());
tbb::parallel_for(size_t{0}, input.size(), [&](size_t i)
{
output[i] = input[i] * 2;
}
Keep in mind that resizing vectors (and more generally working on dynamically sized data) in a parallel context is often a bad idea.
Upvotes: 0