Я написал следующий параллельный код для проверки всех элементов вектора вектора. Я сохраняю только те элементы из vector<vector<int> >
, которые удовлетворяют заданному условию. Однако моя проблема заключается в том, что некоторые из векторов в пределах vector<vector<int> >
довольно большие, а другие довольно маленькие. В связи с чем мой код занимает много времени, чтобы выполнить thread.join(). Кто-то может предложить, как я могу улучшить производительность моего кода.Проблемы с производительностью при соединении потоков
void check_if_condition(vector<int>& a, vector<int>& satisfyingElements)
{
for(vector<int>::iterator i1=a.begin(), l1=a.end(); i1!=l1; ++i1)
if(some_check_condition(*i1))
satisfyingElements.push_back(*i1);
}
void doWork(std::vector<vector<int> >& myVec, std::vector<vector<int> >& results, size_t current, size_t end)
{
end = std::min(end, myVec.size());
int numPassed = 0;
for(; current < end; ++current) {
vector<int> satisfyingElements;
check_if_condition(myVec[current], satisfyingElements);
if(!satisfyingElements.empty()){
results[current] = satisfyingElements;
}
}
}
int main()
{
std::vector<std::vector<int> > myVec(1000000);
std::vector<std::vector<int> > results(myVec.size());
unsigned numparallelThreads = std::thread::hardware_concurrency();
std::vector<std::thread> parallelThreads;
auto blockSize = myVec.size()/numparallelThreads;
for(size_t i = 0; i < numparallelThreads - 1; ++i) {
parallelThreads.emplace_back(doWork, std::ref(myVec), std::ref(results), i * blockSize, (i+1) * blockSize);
}
//also do work in this thread
doWork(myVec, results, (numparallelThreads-1) * blockSize, myVec.size());
for(auto& thread : parallelThreads)
thread.join();
std::vector<int> storage;
storage.reserve(numPassed.load());
auto itRes = results.begin();
auto itmyVec = myVec.begin();
auto endRes = results.end();
for(; itRes != endRes; ++itRes, ++itmyVec) {
if(!(*itRes).empty())
storage.insert(storage.begin(),(*itRes).begin(), (*itRes).end());
}
std::cout << "Done" << std::endl;
}
Любая причина не говорить более читаемые 'itres-> begin()'? И 'empty' должен быть вызовом функции. –
Отсутствие причины как такового, но если (itRes-> begin()) и if (! (* ItRes) .empty()) имеют тот же эффект. –
Очевидно, что нет, поскольку они называют разные функции. –