C++ boost条件互斥的性能较差
我不熟悉使用条件变量,所以我很容易在这里做一些愚蠢的事情,但是当我使用boost线程时,与直接调用函数相比,我得到了一些奇怪的性能。如果我将在func上创建boost线程的行更改为直接调用func,那么代码的运行速度会更快。我已经尝试过使用SourceForge的boost threadpool软件,但没有任何区别 代码如下:C++ boost条件互斥的性能较差,c++,boost-thread,C++,Boost Thread,我不熟悉使用条件变量,所以我很容易在这里做一些愚蠢的事情,但是当我使用boost线程时,与直接调用函数相比,我得到了一些奇怪的性能。如果我将在func上创建boost线程的行更改为直接调用func,那么代码的运行速度会更快。我已经尝试过使用SourceForge的boost threadpool软件,但没有任何区别 代码如下: #include <boost/thread.hpp> using namespace boost; condition_variable cond;
#include <boost/thread.hpp>
using namespace boost;
condition_variable cond;
mutex conditionalMutex;
int numThreadsCompleted = 0;
int numActiveThreads = 0;
void func()
{
{
lock_guard<mutex> lock(conditionalMutex);
--numActiveThreads;
numThreadsCompleted++;
}
cond.notify_one();
};
int main()
{
int i=0;
while (i < 100000)
{
if (numActiveThreads == 0)
{
++numActiveThreads;
thread thd(func);
//Replace above with a direct call to func for several orders of magnitude
//performance increase...
++i;
}
else
{
unique_lock<mutex> lock(conditionalMutex);
while (numThreadsCompleted == 0)
{
cond.wait(lock);
}
numThreadsCompleted--;
}
}
return 0;
}
#包括
使用名称空间boost;
条件变量cond;
互斥条件mutex;
int numThreadsCompleted=0;
int numativethreads=0;
void func()
{
{
锁和防护锁(条件Mutex);
--纽曼提维思;
numThreadsCompleted++;
}
第二,通知某人;
};
int main()
{
int i=0;
而(i<100000)
{
if(numativethreads==0)
{
++纽曼提维思;
螺纹thd(func);
//将上述内容替换为直接调用func几个数量级
//性能提高。。。
++一,;
}
其他的
{
唯一锁(conditionalMutex);
while(numThreadsCompleted==0)
{
等待(锁定);
}
numthreads已完成--;
}
}
返回0;
}
您正在创建和销毁线程,这些线程通常作为一些较低级别的操作系统结构实现,通常是某种轻量级进程。这种创造和毁灭可能代价高昂
最后,你基本上做到了
一遍又一遍。这意味着创建/销毁线程,而您每次都在这样做,因此成本将不断增加。除了创建和销毁线程的开销之外,还可能导致性能的差异 如果没有线程,if语句始终为true,因为在每个循环迭代的开始和结束时,
numativethreads
将为0
:
while (i < 100000)
{
if (numActiveThreads == 0) // branch always taken
{
++numActiveThreads; // numActiveThreads = 1
func(); // when this returns, numActiveThreads = 0
++i;
}
}
while(i<100000)
{
if(numativethreads==0)//始终执行分支
{
++numativethreads;//numativethreads=1
func();//返回时,numativethreads=0
++一,;
}
}
这导致:
- 分支预测永远不会失败
- 没有线程创建/销毁的开销
- 等待获取
的时间没有被阻塞conditionalMutex
numativethreads
在连续迭代中可能是0
。在我测试的大多数机器上,观察到了短的可预测模式,在每次迭代中if语句和else语句之间交替出现分支。但是,有时在连续迭代中选择if语句。因此,时间可能浪费在以下方面:
- 分支预测失败
- 线程的创建和销毁。如果创建和销毁是并发的,那么同步可能发生在底层线程库中
- 阻止等待获取
或等待条件互斥
条件
int main()
{
int i=0;
while (i < 100000)
{
thread thd(func);
thd.join();
++i;
}
return 0;
}
intmain()
{
int i=0;
而(i<100000)
{
螺纹thd(func);
thd.join();
++一,;
}
返回0;
}
没有理由认为这比:
int main()
{
int i=0;
while (i < 100000)
{
func();
++i;
}
return 0;
}
intmain()
{
int i=0;
而(i<100000)
{
func();
++一,;
}
返回0;
}
我认为创建和销毁线程的开销也是个问题,所以我尝试了线程池:使用boost::thread时34秒,使用ThreadPool时7秒,使用函数调用时0.16秒。这是在增加循环长度以给出更大的数字之后……理论上,分支预测惩罚不应该是导致性能下降的一个大因素。一个分支上的一次未命中预测通常花费不到100个周期,而线程创建和销毁可能会消耗更多的cpu。