несколько потоков для векторной обработки - PullRequest
1 голос
/ 12 июля 2020

У меня есть 2 вектора с некоторыми именами файлов и функцией, которые обрабатывают эти файлы:

vector<string> vecFilenames1; // {filename1_1, filename1_2, filename1_3, ...}
vector<string> vecFilenames2; // {filename2_1, filename2_2, filename2_3, ...}

Эти векторы имеют одинаковый размер. Как я сейчас обрабатываю:

// function for processing
void doSomeStuff() {// ...}
// processing loop
for (int i = 0; i < vecFilenames1.size();i++) {
    doSomeStuff(vecFilenames1[i], vecFilenames2[i]);
}

У меня 4 потока (2 ядра), и я хочу сделать такой процесс быстрее, как я могу это сделать?

EDIT 1

Я использую компилятор mingw:

g++ (MinGW.org GCC-8.2.0-5) 8.2.0
Copyright (C) 2018 Free Software Foundation, Inc.

Нужно ли мне менять его на более новую версию для облегчения решения моей проблемы?

EDIT 2

Я обновил свой g cc:

g++.exe (MinGW.org GCC Build-2) 9.2.0
Copyright (C) 2019 Free Software Foundation, Inc.

1 Ответ

2 голосов
/ 12 июля 2020

Вы должны разделить вектор на диапазоны и обработать каждый диапазон в потоке пула потоков.

Параллельные алгоритмы C ++ 17 - простой способ sh этого добиться. Используя алгоритм std, вам не нужно делать такие вещи, как вектор разделения и вызов пула потоков вручную.

Вы можете использовать библиотеку Intel TBB или директивы Open MP для достижения аналогичных результатов без поддержки C ++ 17.

Или накатайте собственную реализацию. std::async - запустить задачу пула потоков, std::hardware_concurrency - получить оценку количества ядер

Пример параллельного for_each:

#include <algorithm>
#include <chrono>
#include <iostream>
#include <execution>
#include <mutex>
#include <string>
#include <thread>

using namespace std;

vector<string> vecFilenames1;
vector<string> vecFilenames2;

int main() {
    for (int i = 1; i < 1000; i++)
    {
        vecFilenames1.push_back("filename1_" + to_string(i));
        vecFilenames2.push_back("filename2_" + to_string(i));
    }

    mutex m;

    auto f = [&](const string& fn1)
    {
        // Comupute other element via pointer arthimetics
        // Works only with vector, for, say, deque, use container of struct
        const string& fn2 = vecFilenames2[&fn1 - vecFilenames1.data()];

        // simulate processing (to hide mutex unfairness and make threads
        // working concurrently)
        // replace with read processing
        using namespace chrono_literals;
        this_thread::sleep_for(30ms);

        // avoid doing any real work under the lock to benefit from paralleling
        lock_guard<mutex> guard(m);

        // ideally don't do console i/o from thread pool in real code
        cout << "Processing " << fn1 << " & " << fn2
            << " from " << this_thread::get_id() << '\n';
    };

    for_each(execution::par, vecFilenames1.begin(), vecFilenames1.end(), f);

    return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...