1

異なるスレッドで処理する必要がある巨大なベクトルがあるため、同じデータで N 個の異なるベクトルを作成する代わりに、イテレータを使用することを考えました。コードはなんとかできましたが、短縮または改善できる可能性があるようです。

        Iterator begin = vec.begin();
        Iterator end;
        Iterator endOfVector = vec.end(); 

        while(end != endOfVector){
            end = begin;

            advance(end, elementsPerThread);
            if (end > endOfVector){
                end = endOfVector;
            }

            iteratorPairs.push_back( std::make_pair(begin, end) );

            begin = end;
        }

私は C++/Qt プログラミングにかなり慣れていますが、std:: に関しては、まだまだ学ぶべきことがたくさんあると感じています。:)

4

2 に答える 2

3

私はそれを少し違う方法で行うと思います。毎回ベクトルの終わりを通過したかどうかを確認する代わりに、適合するペアの数を計算することから始めます。できる限り、それらをうまく適合させようとすることもできます。たとえば、スレッドごとに最大 100 個の要素があり、合計で 550 個の要素があるとします。あなたのやり方では、それぞれ 100 要素の 5 つの範囲と、50 要素の 1 つの範囲になります。

合計で 6 つの範囲を使用する場合は、通常、これらの 6 つの範囲にできるだけ均等にワークロードを分散することをお勧めします。そのため、範囲ごとに 550/6 = 91 または 92 の要素 (および奇数サイズの 1 つの範囲) を実行します。違いを補うため)。

typedef std::vector<int>::iterator it;   
typedef std::pair<it, it> p;

std::vector<p> split(std::vector<int> const &v, size_t elementsPerThread) {
    std::vector<p> ranges;

    size_t range_count = (v.size()+1) / elementsPerThread+1;
    size_t ePT = v.size() / range_count;

    size_t i;

    it b = v.begin();

    for (i=0; i<v.size()-ePT; i+=ePT)
        ranges.push_back(std::make_pair(b+i, b+i+ePT));

    ranges.push_back(std::make_pair(b+i, v.end()));
    return ranges;
}
于 2013-02-22T17:06:15.843 に答える
0

あなたが抱えている問題は

advance(end, elementsPerThread);

その理由は、前進がベクトルの終わりを超えて、未定義の動作を引き起こすためです。交換します

        advance(end, elementsPerThread);
        if (end > endOfVector){
            end = endOfVector;
        }

advance(end,std::min(elementsPerThread,endOfVector - end));

その後、前進はベクトルの終わりを超えません

于 2013-02-22T17:02:19.417 に答える