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 の使用に制限されていることにも言及する必要があります。そのため、ベクターを分割し、ベクターの各部分を特定のスレッド専用にしようとしました。

任意のアイデアをいただければ幸いです。

4

1 に答える 1

3

フィルター反復子を作成するときに、間違った開始インデックスと停止インデックスを使用しています。作業例を添付しました。s を使用して、parallel 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;
        }
    }
}
于 2016-12-12T12:02:03.507 に答える