为什么OpenMP的性能优于线程

Why is OpenMP outperforming threads?

本文关键字:线程 于线程 OpenMP 性能 为什么      更新时间:2023-10-16

我一直在OpenMP 中调用这个

#pragma omp parallel for num_threads(totalThreads)
for(unsigned i=0; i<totalThreads; i++)
{
workOnTheseEdges(startIndex[i], endIndex[i]);
}

在C++11中,std::threads(我相信这些只是pthread)

vector<thread> threads;
for(unsigned i=0; i<totalThreads; i++)
{
threads.push_back(thread(workOnTheseEdges,startIndex[i], endIndex[i])); 
}
for (auto& thread : threads)
{
 thread.join();
}

但是,OpenMP的实现速度是原来的两倍--更快!我本以为C++11线程会更快,因为它们更低级。注意:上面的代码在一个循环中不仅被调用一次,而且可能被调用10000次,所以这可能与此有关?

编辑:为了澄清,在实践中,我要么使用OpenMP,要么使用C++11版本,而不是两者都使用。当我使用OpenMP代码时,需要45秒,当我使用C++11时,需要100秒。

totalThreads在您的OpenMP版本中来自哪里?我打赌它不是startIndex.size()

OpenMP版本将请求排队到totalThreads工作线程上。看起来C++11版本创建了startIndex.size()线程,如果这是一个很大的数字,那么这将涉及大量的开销。

请考虑以下代码。OpenMP版本在0秒内运行,而C++11版本在50秒内运行。这不是因为函数是doNothing,也不是因为向量在循环中。正如您所能想象的,在每次迭代中,都会创建并销毁c++11线程。另一方面,OpenMP实际上实现了线程池。它不在标准中,但在英特尔和AMD的实现中。

for(int j=1; j<100000; ++j)
{
    if(algorithmToRun == 1)
    {
        vector<thread> threads;
        for(int i=0; i<16; i++)
        {
            threads.push_back(thread(doNothing));
        }
        for(auto& thread : threads) thread.join();
    }
    else if(algorithmToRun == 2)
    {
        #pragma omp parallel for num_threads(16)
        for(unsigned i=0; i<16; i++)
        {
            doNothing();
        }
    }
}