好吧,标题很好地总结了它。我通过分析到达了这个丑陋的地方。我通常使用 Open MP 2.0,但据我所知,使用 OMP2.0 并不容易。我正在使用 Concurrency::parallel_for,但我似乎无法让它工作。
所以我有一个名为 unallocated 的 Obj 对象列表,如果它们满足特定条件,我想将其删除。由于我无法在循环本身内并行删除它们,因此我尝试将迭代器存储到另一个名为 preallocated 的序列中 unallocated 中的相应位置,我将用于稍后在串行循环中调用 list::erase() 函数。
这是我目前所拥有的:
// (std::list<Obj> unallocated is already created and full of Obj objects)
typedef std::list<Obj>::iterator ItUnallocated;
concurrency::concurrent_vector<ItUnallocated> preallocated;
// We can now do a parallelised search through all remaining elments of unallocated to
//check if the cell pointer collides with any other unallocated cells, which will be added to
// the preallocated sequence.
concurrency::parallel_for
(
unallocated.begin(),
unallocated.end(),
[&](ItUnallocated const it)
{
if (Criterion(*it)) // check if the criterion is met
{
// criterion is met! Add the iterator
preallocated.push_back(it);
}
}
);
// run through each element of *preallocated* in serial and call unallocated.erase() for each of the elements.
编译这个,我得到以下错误:
C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\ppl.h(3447): error C2440: '' : cannot convert from 'int' to 'std::_List_iterator<_Mylist>'
我在这里做错了什么(除了我创造了一个可憎的事实)。请有建设性的批评;我知道这很糟糕,我们很乐意考虑更好的解决方案!
注意:我正在使用一个列表,因为它的 vector 在最后一部分太慢(运行预分配并删除迭代器位置)。
最佳答案
parallel_for
只接受整数类型作为边界。您可以保留这个想法,并在索引上使用带有 parallel_for
循环的 vector
:
typedef std::vector<Obj>::iterator ItUnallocated;
std::vector<Obj> unallocated;
concurrency::concurrent_vector<ItUnallocated> preallocated;
concurrency::parallel_for<size_t>
(
0,
unallocated.size(),
[&](size_t index)
{
if(Criterion(unallocated[index]))
preallocated.push_back(unallocated.begin() + index);
}
);
另请注意,并发性
仅适用于 Microsoft。您可能想使用非常相似的 Intel thread Building Blocks library ,这是可移植的。
关于c++ - 如何有选择地从序列中并行删除对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17405628/