Reputation: 643
I have 2 vectors with some filenames and function that process this files:
vector<string> vecFilenames1; // {filename1_1, filename1_2, filename1_3, ...}
vector<string> vecFilenames2; // {filename2_1, filename2_2, filename2_3, ...}
This vectors have same size. How I process now:
// function for processing
void doSomeStuff() {// ...}
// processing loop
for (int i = 0; i < vecFilenames1.size();i++) {
doSomeStuff(vecFilenames1[i], vecFilenames2[i]);
}
I have 4 threads (2 cores) and I want do such a process faster, how could I do that?
EDIT 1
I use mingw compiler:
g++ (MinGW.org GCC-8.2.0-5) 8.2.0
Copyright (C) 2018 Free Software Foundation, Inc.
Do I need to change it to newer version for easy solving my problem?
EDIT 2
I updated my gcc:
g++.exe (MinGW.org GCC Build-2) 9.2.0
Copyright (C) 2019 Free Software Foundation, Inc.
Upvotes: 1
Views: 482
Reputation: 13739
You should partition vector into ranges and process each range in a threadpool thread.
C++17 parallel algorithms is an easy way to accomplish this. By using std algorithm, you don't need to do things like partitioning vector, and calling thread pool manually.
You can use Intel TBB library or Open MP directives to achieve similar without C++17 support.
Or roll your own implementation. std::async
is to run a thread pool task, std::hardware_concurrency
to get the estimate on number of cores
Example of parallel 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;
}
Upvotes: 2