Доброе утро всем.
Я новичок в теме многопоточности 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:
- Размеры матрицы в направлениях Ox и Oy соответственно: size_t nx_ , size_t ny_ .
- Вектор размера (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. Извините за неправильное представление первой строки в операторе + =. Не удалось решить эту проблему: (