将std :: vector分成N对迭代器的最佳方法,范围为“Y”

时间:2013-02-22 16:15:41

标签: c++ iterator stdvector

我有一个巨大的向量,我需要在不同的线程中处理,所以我没有使用相同的数据创建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 ::我觉得我还有很多需要学习的东西。 :)

2 个答案:

答案 0 :(得分:3)

我想我会做的有点不同。我没有检查我们是否每次都通过了向量的末尾,而是开始计算适合的对的数量。只要我们在这里,我们也可以尝试尽可能地适应它们 - 例如,让我们假设每个线程最多有100个元素,总共550个元素。按照你的方式,我们最终得到5个范围,每个100个元素,一个50个元素。

如果我们总共有6个范围,我们通常会在这6个范围内尽可能均匀地分配工作负载,因此我们每个范围执行550/6 = 91或92个元素(以及一个奇怪的大小来弥补差异。)

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;
}

答案 1 :(得分:0)

你遇到的问题是

advance(end, elementsPerThread);

原因是提前将超过向量的末尾,导致未定义的行为。我会替换

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

使用

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

然后前进不会超过向量的结尾