parallel_for写入未排序的向量

时间:2014-01-14 13:31:00

标签: c++11 parallel-processing visual-studio-2013

我有一个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中写一个共享向量根本不可能这么简单吗?

1 个答案:

答案 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是更高效还是可组合。关键是要明白我们也可以使用无锁容器来完成这项工作。