4

我正在寻找将 aconcurrent_vector从 PPL 库转换为普通 std::vector 的推荐方法。

我有一个函数,它以 a 形式返回其结果,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;
}

关于如何正确执行此操作有什么建议吗?


编辑:
与往常一样,我忽略了最明显的简化(克里斯建议):

std::vector<Foo> Bar() {
    concurrency::concurrent_vector<Foo> cv;

    //Fill cv in a parallel algorithm

    return std::vector<Foo>(cv.begin(), cv.end());
}

虽然它(很可能)没有摆脱它看起来更干净的副本。

编辑2:

这让我想到 - 假设没有办法显式阻止向量数据的副本 - 编译器在仍然应用RVO或对函数的返回值进行移动操作

4

2 回答 2

4

假设没有办法显式阻止向量数据的副本 - 编译器可以优化副本(从并发到 std::vector)的可能性有多大,同时仍然对函数的返回应用 RVO 或移动操作价值?

concurrent_vector与完全不同std::vector特别是,它的数据存储在内存中不是连续的,正如std::vector需要的那样。因此,您寻求的转换是不可能的,无论是显式的还是作为编译器优化;数据需要从一个位置复制到另一个位置。

于 2014-08-14T12:22:06.863 回答
0

另一种选择是始终使用std::vector并行算法。

算法和容器通常是独立/正交的,因此您可以使用例如并行模式下的标准算法与 g++,同样适用于TBB 算法

于 2014-06-06T09:08:27.093 回答