我正在寻找将concurrent_vector
从PPL库转换为普通std :: vector的推荐方法。
我有一个函数可以在std::vector
中返回结果,但可能会也可能不会在内部使用并行算法。目前我正在使用insert
将并发向量中的元素复制到法线向量:
#ifdef PARALLEL
std::vector<Foo> Bar() {
concurrency::concurrent_vector<Foo> cv;
//Fill cv in a parallel algorithm
std::vector<Foo> sv;
sv.insert(sv.begin(), cv.begin(), cv.end());
return sv;
}
#else
std::vector<Foo> Bar() {
std::vector<Foo> sv;
//Fill sv in a sequential algorithm
return sv;
}
#endif
虽然插入操作的性能目前不是真正的发布(与功能体相比),但似乎没必要,我想知道是否有更好的解决方案(顺便说一句:Foo
是一个简单的POD,不能移动)。
理想情况下,我希望有类似的内容
std::vector<Foo> Bar() {
concurrency::concurrent_vector<Foo> cv;
//Fill cv in a parallel algorithm
return static_cast<std::vector<Foo>>(cv);
}
或至少
std::vector<Foo> Bar() {
concurrency::concurrent_vector<Foo> cv;
//Fill cv in a parallel algorithm
std::vector<Foo> sv(std::move(cv));
return sv;
}
有关于如何正确执行此操作的建议吗?
编辑:
一如既往,我忽略了最明显的简化(Chris建议):
std::vector<Foo> Bar() {
concurrency::concurrent_vector<Foo> cv;
//Fill cv in a parallel algorithm
return std::vector<Foo>(cv.begin(), cv.end());
}
虽然它(很可能)没有摆脱副本,但它看起来更清洁。
EDIT2:
这引出了我的假设 - 假设没有办法明确地阻止矢量数据的副本 - 编译器有多大可能优化副本(从并发到std :: vector),而对函数的返回值
应用RVO
或移动操作
答案 0 :(得分:3)
来自假设没有办法明确地阻止矢量数据的副本 - 编译器有多大可能优化副本(从并发到std :: vector),同时仍然应用RVO或移动操作功能&#39;返回值?
concurrent_vector
的{p> std::vector
为quite different。特别是,它的数据存储在内存中不是连续的,正如std::vector
所要求的那样。因此,无论是显式转换还是编译器优化,您所寻求的转换都是不可能的;数据需要从一个位置复制到另一个位置。
答案 1 :(得分:0)
另一种选择是始终将std::vector
与并行算法一起使用。
算法和容器通常是独立的/正交的,因此您可以使用Parallel Mode with g++中的标准算法,同样适用于TBB algorithms。