我有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个核心),我想做这样一个进程更快,我怎么能做到呢?
编辑%1
我使用mingw编译器:
g++ (MinGW.org GCC-8.2.0-5) 8.2.0
Copyright (C) 2018 Free Software Foundation, Inc.
我是否需要将其更改为新版本以方便解决我的问题?
编辑2
我更新了我的GCC:
g++.exe (MinGW.org GCC Build-2) 9.2.0
Copyright (C) 2019 Free Software Foundation, Inc.
您应该将vector划分为多个范围,并在一个线程池线程中处理每个范围。
C++17并行算法是实现这一目标的一种简单方法。 通过使用std算法,您不需要做诸如分区vector和手动调用线程池之类的事情。
您可以使用Intel TBB库或打开MP指令来实现类似,而无需C++17支持。
或者滚动您自己的实现。 std::async
是运行一个线程池任务,std::hardware_concurrency
是获取核数的估计值
并行for_eace
示例:
#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;
}