2016-12-12 4 views
0

大きなベクトルがあります。正のメンバーだけを並行して増やしたいと思います。openMP v。2.0を使用してフィルタイテレータを並列化

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を使用するように制限されていることにも言及しなければなりません。 そのため、私は自分のベクトルを分割して、ベクトルの各部分を特定のスレッドに割り当てようとしました。

いずれかのアイデアをいただければ幸いです。

答えて

3

フィルタイテレータを作成するときに、間違った開始インデックスと停止インデックスを使用します。私は実際の例を付けました。私は並列のステートメント内でスレッドを選択するためにsを使いました。あなたのバージョンがあまりにも機能しているかどうかわからないので、私はそれを慣れ親しんだものに変更しました。

#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; 
     } 
    } 
} 
関連する問題