vendredi 30 décembre 2016

Performance issues in joining threads

I wrote the following parallel code for examining all elements in a vector of vector. I store only those elements from vector<vector<int> > which satisfy a given condition. However, my problem is some of the vectors within vector<vector<int> > are pretty large while others are pretty small. Due to which my code takes a long time to perform thread.join(). Can someone please suggest as to how can I improve the performance of my code.

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<bool> >& 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<bool> > 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;
}

Aucun commentaire:

Enregistrer un commentaire