大佬教程收集整理的这篇文章主要介绍了C++:如何在 n 个范围上并行化 n 元运算?,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
两个范围内的二元运算可以通过这种方式并行化:
#include <Cassert>
#include <algorithm>
#include <vector>
#include <execution>
std::vector<int> add(const std::vector<int>& A,const std::vector<int>& B) {
assert(A.size() == B.size());
std::vector<int> c;
C.reserve(A.size());
std::transform(std::execution::par_unseq,A.begin(),A.end(),B.begin(),std::BACk_inserter(C),std::plus<>{});
return c;
}
我想通过求和 n 个参数(或任何 n 元运算)将其扩展到 n 个范围。范围的数量 n 在编译时是未知的。
std::transform
不提供这样做。我该怎么办?
我想要这样的东西:
#include <algorithm>
#include <Cassert>
#include <vector>
#include <ranges>
std::vector<int> addn (const std::vector<std::vector<int>>& Rs) {
const std::size_t n = Rs[0].size();
assert(std::ranges::all_of(Rs,[&n](const auto& R){return R.size() == n;}));
std::vector<int> res(n);
// want to parallelize
for (std::size_t i = 0; i < n; ++i) {
for (const auto& R : Rs) {
res[i] += R[i];
}
}
return res;
}
如果您有一个嵌套的 for 循环,并且想将其转换为使用 STL 算法,那么通常的技巧是嵌套 STL 算法。如果您想对每一行求和,那么 for 循环将如下所示:
for (auto row: Rs) {
int sum = 0;
for (auto col: row)
sum += R;
res.push_BACk(sum);
}
然后转换为算法会相对容易:内循环可以用std::accumulate
代替:
for (auto row: Rs) {
res.push_BACk(std::accumulate(row.begin(),row.end(),0);
}
然后可以将外循环转换为对 std::transform()
的调用。最终的函数看起来像:
std::vector<int> sum_each_row(const std::vector<std::vector<int>>& Rs) {
const std::size_t n = Rs.size();
std::vector<int> res(n);
std::transform(std::execution::par_unseq,Rs.begin(),Rs.end(),res.begin(),[](auto&& row) {
return std::accumulate(row.begin(),0);
});
return res;
}
您可以使用 std::reduce(std::execution::par_unseq,...)
代替 std::accumulate()
进行进一步的并行化,但很可能只需将外循环并行化就足够了。
然而,如果我们想对每一列求和,事情就会变得更加混乱。我们可以做的是对 Rs
中第一行的元素进行并行变换,并尝试获取该元素的索引,如下所示:
std::transform(std::execution::par_unseq,Rs[0].begin(),Rs[0].end(),[&](auto&& col) {
size_t i = &col - &Rs[0].front();
...
}
一旦我们有了列索引 i
,我们可以手动执行 for
循环来对该列求和,或者再次使用类似的技巧来使用 STL 算法。这是一个可能的实现:
std::vector<int> sum_each_column(const std::vector<std::vector<int>>& Rs) {
const std::size_t n = Rs[0].size();
std::vector<int> res(n);
std::transform(std::execution::par_unseq,[&](auto&& col) {
size_t i = &col - &Rs[0].front();
return std::transform_reduce(Rs.begin(),std::plus<>(),[i](auto&& row) {
return row[i];
});
});
return res;
}
以上是大佬教程为你收集整理的C++:如何在 n 个范围上并行化 n 元运算?全部内容,希望文章能够帮你解决C++:如何在 n 个范围上并行化 n 元运算?所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。