作者热门文章
- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
OpenMP 4.5+ 提供了在 C++ 中进行 vector/数组缩减的功能 (press release)
使用所述功能允许我们编写,例如:
#include <vector>
#include <iostream>
int main(){
std::vector<int> vec;
#pragma omp declare reduction (merge : std::vector<int> : omp_out.insert(omp_out.end(), omp_in.begin(), omp_in.end()))
#pragma omp parallel for default(none) schedule(static) reduction(merge: vec)
for(int i=0;i<100;i++)
vec.push_back(i);
for(const auto x: vec)
std::cout<<x<<"\n";
return 0;
}
问题是,在执行此类代码时,各种线程的结果可能以任何方式排序。
有没有办法强制执行顺序,使线程 0 的结果先于线程 1,依此类推?
最佳答案
缩减顺序未明确指定。 (“在 OpenMP 程序中组合值的位置以及组合值的顺序合并的值未指定。”,OpenMP 4.5 中的 2.15.3.6。因此您不能使用缩减。
一种方法是使用 ordered 如下:
std::vector<int> vec;
#pragma omp parallel for default(none) schedule(static) shared(vec)
for(int i=0;i<100;i++) {
// do some computations here
#pragma omp ordered
vec.push_back(i);
}
请注意,vec
现在是共享的,ordered
表示线程间执行和同步的序列化。这对性能可能非常不利,除非您的每个计算都需要大量且统一的时间。
您可以自定义订购减少。从 for
循环中拆分 parallel
区域,并按顺序手动插入本地结果。
std::vector<int> global_vec;
#pragma omp parallel
{
std::vector<int> local_vec;
#pragma omp for schedule(static)
for (int i=0; i < 100; i++) {
// some computations
local_vec.push_back(i);
}
for (int t = 0; t < omp_get_num_threads(); t++) {
#pragma omp barrier
if (t == omp_get_thread_num()) {
global_vec.insert(local_vec.begin(), local_vec.end())
}
}
}
关于c++ - 如何在 OpenMP 中进行有序缩减,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44538200/
我是一名优秀的程序员,十分优秀!