C++ 为什么OpenMP的性能优于线程?

C++ 为什么OpenMP的性能优于线程?,c++,multithreading,c++11,C++,Multithreading,C++11,我一直在用OpenMP调用这个 #pragma omp parallel for num_threads(totalThreads) for(unsigned i=0; i<totalThreads; i++) { workOnTheseEdges(startIndex[i], endIndex[i]); } 用于num_线程(totalThreads)的pragma omp parallel 对于(unsigned i=0;i在OpenMP版本中,totalThreads来自哪里?我打

我一直在用OpenMP调用这个

#pragma omp parallel for num_threads(totalThreads)
for(unsigned i=0; i<totalThreads; i++)
{
workOnTheseEdges(startIndex[i], endIndex[i]);
}
用于num_线程(totalThreads)的pragma omp parallel
对于(unsigned i=0;i在OpenMP版本中,
totalThreads
来自哪里?我打赌它不是
startIndex.size()


OpenMP版本将请求排队到
totalThreads
工作线程上。它看起来像是C++11版本创建的,
startIndex.size()
线程,如果这是一个很大的数字,则会产生非常大的开销。

考虑以下代码。OpenMP版本在0秒内运行,而C++11版本在50秒内运行。这不是因为函数什么都没有做,也不是因为向量在循环中。正如您所想象的,C++11线程是在每次迭代中创建然后销毁。另一方面,OpenMP实际上实现了线程池。它不在标准中,但在Intel和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();
        }
    }
}

for(int j=1;jpresubly OpenMP不会生成数千个线程…我的水晶球无法显示
totalThreads
的值是多少,CPU有多少内核/HW线程,startIndex的大小是多少,以及执行
workintheseedges()需要多少时间
一次。他们做的不是同一件事。OpenMP版本在16个线程上分配10000个任务。C++11版本在10000个线程上运行10000个任务。线程很昂贵,而且线程比内核多的成本更高。你不能只在每个小任务上抛出新线程(除非您正好有10000个左右的内核可以运行它们)。OpenMP版本会为您解决这个问题。@user2588666:您说过“上面的代码是在循环中调用的”。每次调用时,
std::thread
版本都会创建
totalThreads
新线程,但是
OpenMP
每次执行循环时都会重用相同的16个线程。@user2588666:Visual studio实现
std::async
以重用相同的线程。除此之外,您必须管理自己选择的16个线程f(这对于您的情况来说非常简单。请将
线程设置为静态:)对于混淆表示抱歉,但是startIndex.size()等于totalThreads。除了在
j
的每次迭代中创建/销毁线程之外,可能还有一种方法可以在主循环之外定义它们,并在每次
j
中重新启动它们。
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();
        }
    }
}