我遇到了boost:barrier的性能问题。我测量等待方法调用的时间,对于单线程情况,当等待呼叫重复大约100000时需要大约0.5秒。不幸的是,对于两个线程场景,这个时间扩展到3秒,并且每个线程都会变得更糟(我有8个核心处理器)。
我实现了自定义方法,该方法负责提供相同的功能,而且速度更快。
这种方法工作这么慢是否正常。是否有更快的方法来同步boost中的线程(因此所有线程等待所有线程完成当前作业,然后继续执行下一个任务,只需同步,不需要数据传输)。
我被问到目前的代码。 我想要实现的目标。在循环中我运行一个函数,这个函数可以分成许多线程,但是所有线程都应该在执行另一个运行之前完成当前循环运行。
我目前的解决方案
volatile int barrierCounter1 =0; //it will store number of threads which completed current loop run
volatile bool barrierThread1[NumberOfThreads]; //it will store go signal for all threads with id > 0. All values are set to false at the beginning
boost::mutex mutexSetBarrierCounter; //mutex for barrierCounter1 modification
void ProcessT(int threadId)
{
do
{
DoWork(); //function which should be executed by every thread
mutexSetBarrierCounter.lock();
barrierCounter1++; //every thread notifies that it finish execution of function
mutexSetBarrierCounter.unlock();
if(threadId == 0)
{
//main thread (0) awaits for completion of all threads
while(barrierCounter1!=NumberOfThreads)
{
//I assume that the number of threads is lower than the number of processor cores
//so this loop should not have an impact of overall performance
}
//if all threads completed, notify other thread that they can proceed to the consecutive loop
for(int i = 0; i<NumberOfThreads; i++)
{
barrierThread1[i] = true;
}
//clear counter, no lock is utilized because rest of threads await in else loop
barrierCounter1 = 0;
}
else
{
//rest of threads await for "go" signal
while(barrierThread1[i]==false)
{
}
//if thread is allowed to proceed then it should only clean up its barrier thread array
//no lock is utilized because '0' thread would not modify this value until all threads complete loop run
barrierThread1[i] = false;
}
}
while(!end)
}
答案 0 :(得分:2)
锁定与并发运行相反。锁定争用总是最糟糕的行为。
IOW:线程同步(本身)从不扩展。
解决方案:仅在争用率较低的情况下使用同步原语(线程需要同步&#34;相对很少&#34; [1] ),或不要尝试为争用共享资源的作业使用多个线程。
通过让所有线程始终等待,您的基准似乎放大了最坏情况的行为。如果你在所有工人之间的工作量很大,那么开销就会减少,而且可能很容易变得微不足道。
[1] 这是高度相对和主观的