Using BinaryOp within std::reduce() from lt;numericgt; with parallel execution policy(在具有并行执行策略的lt;numericgt;中使用std::Reduce()中的BinaryOp)
问题描述
我在使用<numeric>
STL标头中的std::reduce()
函数时找不到问题。
由于我找到了解决方法,我将显示第一个预期行为:
uint64_t f(uint64_t n)
{
return 1ull;
}
uint64_t solution(uint64_t N) // here N == 10000000
{
uint64_t r(0);
// persistent array of primes
const auto& app = YTL::AccumulativePrimes::global().items();
auto citEnd = std::upper_bound(app.cbegin(), app.cend(), 2*N);
auto citBegin = std::lower_bound(app.cbegin(), citEnd, N);
std::vector<uint64_t> v(citBegin, citEnd);
std::for_each(std::execution::par,
v.begin(), v.end(),
[](auto& p)->void {p = f(p); });
r = std::reduce(std::execution::par, v.cbegin(), v.cend(), 0);
return r; // here is correct answer: 606028
}
但是如果我想避免中间向量,而是在reduce()
本身中就地应用二元运算符,也是并行的,它每次都会给我一个不同的答案:
uint64_t f(uint64_t n)
{
return 1ull;
}
uint64_t solution(uint64_t N) // here N == 10000000
{
uint64_t r(0);
// persistent array of primes
const auto& app = YTL::AccumulativePrimes::global().items();
auto citEnd = std::upper_bound(app.cbegin(), app.cend(), 2*N);
auto citBegin = std::lower_bound(app.cbegin(), citEnd, N);
// bug in parallel reduce?!
r = std::reduce(std::execution::par,
citBegin, citEnd, 0ull,
[](const uint64_t& r, const uint64_t& v)->uint64_t { return r + f(v); });
return r; // here the value of r is different every time I run!!
}
有人能解释一下为什么后一种用法是错误的吗?
我使用的是MS C++编译器cl.exe:版本19.28.29333.0;
Windows SDK版本:10.0.18362.0;
平台工具集:Visual Studio 2019(V142)
C++语言标准:预览-来自最新C++工作草案的功能(/std:C++LATEST)
计算机:Dell XPS 9570 i7-8750H CPU@2.20 GHz,16 GB RAM操作系统:Windows 10 64位
推荐答案
来自cppreference:binary_op
如果binary_op
不是关联的或非可交换的,则行为是不确定的。&q;这是您观察到的;您的行为不是可交换的。
您真正需要的是
std::transform_reduce
。如
r = std::transform_reduce(
std::execution::par, citBegin, citEnd, 0ull,
std::plus<uint64_t>{}, f);
这篇关于在具有并行执行策略的<;numeric>;中使用std::Reduce()中的BinaryOp的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:在具有并行执行策略的<;numeric>;中使用std::Reduce()中的BinaryOp
基础教程推荐
- 如何定义双括号/双迭代器运算符,类似于向量的向量? 2022-01-01
- C++ 程序在执行 std::string 分配时总是崩溃 2022-01-01
- 设计字符串本地化的最佳方法 2022-01-01
- 运算符重载的基本规则和习语是什么? 2022-10-31
- C++ 标准:取消引用 NULL 指针以获取引用? 2021-01-01
- 如何在 C++ 中处理或避免堆栈溢出 2022-01-01
- 调用std::Package_TASK::Get_Future()时可能出现争用情况 2022-12-17
- C++,'if' 表达式中的变量声明 2021-01-01
- 您如何将 CreateThread 用于属于类成员的函数? 2021-01-01
- 什么是T&&(双与号)在 C++11 中是什么意思? 2022-11-04