Using openMP to get the index of minimum element parallelly

前端 未结 3 1541
时光取名叫无心
时光取名叫无心 2021-02-06 10:00

I tried to write this code

float* theArray; // the array to find the minimum value
int   index, i;
float thisValue, min;

index    = 0;
min = theArray[0];
#pragm         


        
3条回答
  •  旧巷少年郎
    2021-02-06 10:16

    Because you're not only trying to find the minimal value (reduction(min:___)) but also retain the index, you need to make the check critical. This can significantly slow down the loop (as reported). In general, make sure that there is enough work so you don't encounter overhead as in this question. An alternative would be to have each thread find the minimum and it's index and save them to a unique variable and have the master thread do a final check on those as in the following program.

    #include 
    #include 
    #include 
    #include 
    #include 
    
    using std::cout;
    using std::vector;
    
    void initializeVector(vector& v)
    {
        std::mt19937 generator(time(NULL));
        std::uniform_real_distribution dis(0.0, 1.0);
        v.resize(100000000);
        for(int i = 0; i < v.size(); i++)
        {
            v[i] = dis(generator);
        }
    }
    
    int main()
    {
        vector vec;
        initializeVector(vec);
    
        float minVal = vec[0];
        int minInd = 0;
    
        int startTime = clock();
    
        for(int i = 1; i < vec.size(); i++)
        {
            if(vec[i] < minVal)
            {
                minVal = vec[i];
                minInd = i;
            }
    
        }
    
        int elapsedTime1 = clock() - startTime;
    
        // Change the number of threads accordingly
        vector threadRes(4, std::numeric_limits::max());
        vector   threadInd(4);
    
        startTime = clock();
    #pragma omp parallel for
        for(int i = 0; i < vec.size(); i++)
        {
            {
                if(vec[i] < threadRes[omp_get_thread_num()])
                {
                    threadRes[omp_get_thread_num()] = vec[i];
                    threadInd[omp_get_thread_num()] = i;
                }
            }
    
        }
    
        float minVal2 = threadRes[0];
        int minInd2 = threadInd[0];
    
        for(int i = 1; i < threadRes.size(); i++)
        {
            if(threadRes[i] < minVal2)
            {
                minVal2 = threadRes[i];
                minInd2 = threadInd[i];
            }
        }
    
        int elapsedTime2 = clock() - startTime;
    
        cout << "Min " << minVal << " at " << minInd << " took " << elapsedTime1 << std::endl;
        cout << "Min " << minVal2 << " at " << minInd2 << " took " << elapsedTime2 << std::endl;
    }
    

    Please note that with optimizations on and nothing else to be done in the loop, the serial version seems to remain king. With optimizations turned off, OMP gains the upper hand.

    P.S. you wrote reduction(min:min_dist) and the proceeded to use min instead of min_dist.

提交回复
热议问题