C++ OpenMP与C++;11线
在下面的示例中,C++11线程执行大约需要50秒,而OMP线程只需要5秒。你知道为什么吗?(我可以向你保证,如果你在做真正的工作,而不是什么都不做,或者如果你按照不同的顺序做,等等,这仍然是正确的)我也在一台16核的机器上C++ OpenMP与C++;11线,c++,multithreading,c++11,C++,Multithreading,C++11,在下面的示例中,C++11线程执行大约需要50秒,而OMP线程只需要5秒。你知道为什么吗?(我可以向你保证,如果你在做真正的工作,而不是什么都不做,或者如果你按照不同的顺序做,等等,这仍然是正确的)我也在一台16核的机器上 #include <iostream> #include <omp.h> #include <chrono> #include <vector> #include <thread> using namespace
#include <iostream>
#include <omp.h>
#include <chrono>
#include <vector>
#include <thread>
using namespace std;
void doNothing() {}
int run(int algorithmToRun)
{
auto startTime = std::chrono::system_clock::now();
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();
}
}
}
auto endTime = std::chrono::system_clock::now();
std::chrono::duration<double> elapsed_seconds = endTime - startTime;
return elapsed_seconds.count();
}
int main()
{
int cppt = run(1);
int ompt = run(2);
cout<<cppt<<endl;
cout<<ompt<<endl;
return 0;
}
#包括
#包括
#包括
#包括
#包括
使用名称空间std;
void doNothing(){}
int运行(int算法运行)
{
auto startTime=std::chrono::system_clock::now();
对于(int j=1;jOpenMP)(也包括和).OpenMP避免了这种开销,因此它所做的只是实际工作和执行状态的最小共享内存穿梭。在线程中,每次迭代都会旋转和拆卸一组新的16个线程。我尝试了一个100循环的代码
花了
OpenMP 0.0727、英特尔TBB 0.6759和C++线程库0.5962毫秒。
我还应用了阿鲁伊斯丹特的建议
void nested_loop(int max_i, int band)
{
for (int i = 0; i < max_i; i++)
{
doNothing(band);
}
}
...
else if (algorithmToRun == 5)
{
thread bristle(nested_loop, max_i, band);
bristle.join();
}
void嵌套循环(int max_i,int band)
{
对于(int i=0;i
这个代码看起来比原来的C++ 11线程部分占用的时间更少。
我猜OpenMP是足够聪明的,可以优化整个循环,因为它是一个NOP。用<代码>线程< /代码>,你正承受着旋转和撕掉所有NOP线程的开销。尝试添加一些实际代码到测试函数中,看看H是什么?appens.嗯,有一件事是,您正在使用一个动态调整大小的容器来容纳线程;这对性能没有帮助。尝试只使用一个固定大小的数组,并在创建时启动它的所有元素。@Aruistante:我添加了真实的代码,我可以向您保证差异仍然存在(我有很多代码,并将其分解到这里发布)--这不是因为NOP。@CoffeeandCode:我已经这样做了(只是再试了一次),差别可以忽略不计,就像对thread()的调用一样无论如何,调用新的。虽然这很好——但我也可以向您保证,这不会影响性能。谢谢。这一定是答案,但您不会认为它需要在外部for循环周围使用#pragma吗?另外,您怎么知道事实上——我在文档中没有看到有关它的信息,即使是在链接的站点中。我相信你是对的,我只是想备份信息。事实上,我从来没有读过他们这样做。查看第二个链接,里面有一些讨论。我可以尝试找到更可靠的文档,我知道我在某处已经明确地读过。这是关于它的另一个讨论。基本上,它实际上不是由OpenMP sta定义的标准,但大多数平台上的大多数实现似乎都能做到这一点,如果它更高效的话。再次感谢:)。我想它一定是线程池,但我只是惊讶地在任何地方都找不到它。在进一步查找之后,我发现了。我将在非intel机器上尝试它,看看它是否仍然成立。你比我先这么做了--它看起来确实基本上在所有实现中都是这样。PS。我可以确认,在AMD机器上也存在差异s