使用 openMP v. 2.0 并行化过滤器迭代器

Posted

技术标签:

【中文标题】使用 openMP v. 2.0 并行化过滤器迭代器【英文标题】:parallelize filter iterator using openMP v. 2.0 【发布时间】:2016-12-12 09:49:11 【问题描述】:

我有一个大向量。我只想并行增加积极的成员。

class is_positive_number 
public:
    bool operator()(int x)  return 0 < x; 
;

int main()

    int numbers_[] =  0, -1, 4, -3, 5, 8, -2, 3, 4, -1 ;
    const int N = sizeof(numbers_) / sizeof(int);   
    std::vector<int> test_vec(numbers_, numbers_ + N);

    std::cout << "max: " << omp_get_max_threads() << std::endl;
    int number_of_threads = 4;
    int SubVecLen = N / number_of_threads,
        LeftOvers = N % number_of_threads;
    int k = 0, i = 0, n = 0;
    std::vector<int> start_vec, end_vec;
    while (n < number_of_threads)
    
        k += i;
        i = (SubVecLen + (LeftOvers-- > 0 ? 1 : 0));
        start_vec.push_back(k);
        end_vec.push_back((k + i - 1));

        ++n;
    
    for (size_t n = 0; n < number_of_threads; n++)
    
        std::cout << start_vec[n] << "\t" << end_vec[n] << "\n";
    

    is_positive_number predicate;
    typedef boost::filter_iterator<is_positive_number, std::vector<int>::iterator>
        FilterIter;

#pragma omp parallel
    
#pragma omp for
        for (int s = 0; s < 4; s++)
        
            FilterIter filter_iter_first(predicate, test_vec.begin(), (test_vec.begin() + start_vec[omp_get_thread_num()]) );
            FilterIter filter_iter_last(predicate, test_vec.begin(), (test_vec.begin() + end_vec[omp_get_thread_num()] + 1) );

            for (auto iter = filter_iter_first;
                iter != filter_iter_last; iter++)
            
                std::cout << "num: " << *iter << std::endl;
                (*iter) = (*iter) + 1;
            

        
    

    for (size_t n = 0; n < test_vec.size(); n++)
    
        std::cout << test_vec[n] << "\n";
    
    return 0;

结果不对!

但是,我要解决的真正问题比这个更复杂。我试图简化我的问题,以便更容易理解。 我还必须提到,我只能使用 openMP v.2.0。 这就是为什么我尝试拆分我的向量并将向量的每个部分专用于特定线程的原因。

任何想法将不胜感激。

【问题讨论】:

【参考方案1】:

您在创建过滤器迭代器时使用了错误的开始和停止索引。我附上了一个工作示例。我使用 s 来选择并行 for 语句中的线程。不确定你的版本是否也可以,所以我把它改成了我习惯的。

#pragma omp parallel

    #pragma omp for
    for (int s = 0; s < 4; s++)
    
        /* The following lines are important */
        FilterIter filter_iter_first(predicate, test_vec.begin() + start_vec[s], (test_vec.begin() + end_vec[s] + 1));
        FilterIter filter_iter_last(predicate, test_vec.begin() + end_vec[s] + 1, (test_vec.begin() + end_vec[s] + 1));

        for (auto iter = filter_iter_first; iter != filter_iter_last; iter++)
        
            std::cout << "num: " << *iter << std::endl;
            (*iter) = (*iter) + 1;
        
    

【讨论】:

以上是关于使用 openMP v. 2.0 并行化过滤器迭代器的主要内容,如果未能解决你的问题,请参考以下文章

嵌套并行 omp v. 2.0 性能

系统地并行化 fortran 2008 `do concurrent`,可能使用 openmp

如何使用 OpenMP 通过 C++ std::list 并行化 for 循环?

在 C++ 中使用 OpenMP 并行化算法

OpenMP指定for循环迭代的线程号

在 C++ 中使用 OpenMP 并行化递归函数