我有一个parallel_for
循环遍历一个大型载体,分析它的不同部分(所有可能的顺序序列,1-2,1-3,1-4,2-3,2-4,等)并将有关这些部分的统计信息存储在另一个未分类的矢量中(使用push_back
)。然后在parallel_for
循环结束后对该向量进行排序。这不可能吗?但是我得到了奇怪的读数,产生的未分类矢量的大小不正确,大约2%的必要迭代丢失(一切正常,正常的循环)。部分问题可能是parallel_for
循环具有不等的工作负载:例如,对于具有100个成员的向量,外循环的第一次运行必须遍历整个100个成员,而最后一次运行只需要从98-100,99-100。
这是代码的简化版本(我在循环中使用unsigned
因为我将它们与索引一起存储):
vector<patchIndex> indexList;
indexList.reserve(2000000);
parallel_for(unsigned(1), units.size(), [&](unsigned n)
{
for (unsigned j = 0; j != (units.size() - n); j++)
{
patchIndex currIndex;
for (auto it = units.begin() + n; it != units.begin() + (j + n + 1); it++)
{
//calculate an index from the (*it).something
}
//some more calculations of the index
indexList.push_back(currIndex);
}
});
sort(indexList.begin(), indexList.end(), [](patchIndex &a, patchIndex &b) {return a.index > b.index; });
// at this point Visual Studio says that "sort is ambiguous" but it compiles anyway
indexList.size()
应为(units.size() + 1) * (units.size()/2)
,但稍微少一些。并且一堆索引只是算法无法正确生成的零。那么,在parallel_for
中写一个共享向量根本不可能这么简单吗?
答案 0 :(得分:0)
除了@ Yakk的建议和concurrent_vector
,您也可以这样做。
combinable<vector<patchIndex>> indexList;
//在循环中。
indexList.local().push_back(currIndex);
//离开循环时。
vector<patchIndex> result;
result.reserve(2000000);
indexList.combine_each([&](patchIndex x)
{
result.push_back(x);
});
sort(result.begin(), result.end()[](patchIndex &a, patchIndex &b) {return a.index > b.index; });
我还没有测试过使用concurrent_vector是更高效还是可组合。关键是要明白我们也可以使用无锁容器来完成这项工作。