当使用par_unseq时,我仍然可以依靠输出元素的顺序吗?

14
阅读完文档后,我仍然对par_unseq的使用方式感到困惑。我知道由于线程和向量化,我无法确定执行顺序,但我是否仍然可以依赖输出的顺序?

阅读完文档后,我仍然对par_unseq的使用方式感到困惑。我知道由于线程和向量化,我无法确定执行顺序,但我是否仍然可以依赖输出的顺序?

transform([x0, x1, x2], f) == [f(x0), f(x1), f(x2)]]
换句话说,这个测试会失败吗?
std::vector<int> xs = {1, 2, 3, 4};
std::vector<int> ys(xs.size());

std::transform(
    std::execution::par_unseq,
    cbegin(xs), cend(xs),
    begin(ys),
    [](int x) { return x*x; });

std::vector<int> expected = {1, 4, 9, 16};
ASSERT_EQ(expected , ys);

据我理解,std::transform 的输出顺序是其规范的一部分,无论选择哪种执行策略,它都不应更改。 - jdehesa
2个回答

11

标准库中的 [alg.transform] 规定:

作用: 将操作 op(*(first1 + (i - result))binary_op(*(first1 + (i - result)), *(first2 + (i - result))) 的结果分别赋值给范围 [result,result + (last1 - first1)) 中的迭代器 i 对应位置。

[algorithms.parallel.overloads] 则是(感谢 @Caleth):

除非另有规定,否则带有 ExecutionPolicy 的算法重载与没有的重载具有相同的语义。

因此,您可以依赖输出的顺序。


2
在[algorithms.parallel.overloads]中,您还有["除非另有规定,否则ExecutionPolicy算法重载的语义与没有重载的相同"](http://eel.is/c++draft/algorithms.parallel#overloads-2)。 - Caleth
谢谢,https://en.cppreference.com/w/cpp/algorithm/transform 没有提到这个行为,但标准似乎非常明确。 - TimW

2

不,你的测试永远不会失败,因为即使执行顺序改变,ys[0...3] = xs[0...3] * xs[0...3] = {1*1, 2*2, 3*3, 4*4};也不会改变。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接