C ++ Как добавить два вектора асинхронно - PullRequest
0 голосов
/ 06 сентября 2018

Доброе утро всем.

Я новичок в теме многопоточности C ++ 11 и пытаюсь записать код, который добавляет два вектора одинакового размера асинхронным способом. Это значит, если у меня есть два вектора:

vector<int> fisrt = {1, 2, 3};
vector<int> second = {3, 2, 1};
first += second; // first = {4, 4, 4}

Я написал класс Paginator, который разбивает вектор на "страницы" с соответствующим page_size. Моя идея добавления векторов асинхронным способом заключается в следующем: разделить векторы на страницах с выбранным размером page_size и добавить страницы первого и второго векторов асинхронным способом.

Реализация класса Paginator

template<class Iter>
class IterRange {
public:
    explicit IterRange(Iter first, Iter last) : first_(first), last_(last) {}

    Iter begin() { return first_; }
    const Iter begin() const { return first_; }

    Iter end() { return last_; }
    const Iter end() const { return last_; }

private:
    Iter first_;
    Iter last_;
};

template<class Iter>
IterRange<Iter> MakeIterRange(Iter first, Iter last) {
    return IterRange<Iter> {first, last };
}

template<class Iter>
class Paginator {
public:
    Paginator(Iter first, Iter last, size_t page_size) : page_size_(page_size) {
        size_t pages_count = static_cast<size_t> (floor((double)distance(first, last) / page_size_));
        pages_.reserve(pages_count);

        size_t page_id = 0u;
        Iter begin_page = first;
        for (page_id, begin_page; page_id < pages_count; ++page_id, begin_page += page_size_) {
            pages_.push_back(MakeIterRange( begin_page,  begin_page + page_size ));
        }

        // If some elements less than page_size_ is left
        if (begin_page != last) {
            pages_.push_back(MakeIterRange(begin_page, begin_page + distance(begin_page, last)));
        }
    }

    auto begin() { return pages_.begin(); }
    auto begin() const { return pages_.begin(); }

    auto end() { return pages_.end(); }
    auto end() const { return pages_.end(); }

private:
    size_t page_size_;
    vector<IterRange<Iter>> pages_;
};

template<class Iter>
Paginator<Iter> MakePaginator(Iter first, Iter last, size_t page_size) {
    return{ first, last, page_size };
}

template<class Container> // And the same for non constant Container
auto Paginate(const Container & c, size_t page_size) {
    return MakePaginator(begin(c), end(c), page_size);
}

Эта процедура Paginate используется в operator + = в моем классе Matrix.

Поля класса Matrix:

  1. Размеры матрицы в направлениях Ox и Oy соответственно: size_t nx_ , size_t ny_ .
  2. Вектор размера (nx_ * ny_), в котором хранятся все элементы в матрице: vector body_ .

Оператор + = для матрицы

шаблон встроенная матрица и матрица :: оператор + = (постоянная матрица и другие) {

size_t threads_numb = thread::hardware_concurrency();
size_t page_size = static_cast<size_t> (ceil((double)body_.size() / threads_numb));
    vector<future<void>> futures;

    auto page_1 = page::Paginate(body_, page_size);
    auto page_2 = page::Paginate(other.body_, page_size);

    auto it_2 = page_2.begin();

    for (auto it = page_1.begin(); it != page_1.end(); ++it, ++it_2) {
        futures.push_back(
            async([it, it_2] { transform(it->begin(), it->end(), it_2->begin(), it->begin(), plus<T>()); })
        );
    }

    return *this;
}

Но в результате я получаю итератор вне диапазона Ошибка! Как я мог это исправить?

P.S. Извините за неправильное представление первой строки в операторе + =. Не удалось решить эту проблему: (

...