简体   繁体   English

C ++ 11中的线程性能

[英]Performance of threads in c++11

I am interested in the performance of mutex and message passing in the latest gcc with threads based on pthreads and a Ubuntu development environment. 我对基于gpthread和Ubuntu开发环境的最新gcc中互斥锁和消息传递的性能感兴趣。 A good generic problem for this is the dining philosophers where each philosopher uses lh and rh fork shared with left and right hand neighbour. 一个很好的通用问题是餐饮哲学家,其中每个哲学家都使用与左右手共享的lh和rh叉子。 I increase the number of philosophers to 99 to keep my quad core processor busy. 为了使我的四核处理器忙碌起来,我将哲学家的数量增加到99名。

    int result = try_lock(forks[lhf], forks[rhf]);

the above code allows my philosopher to attempt to grab the two forks they need to eat with. 上面的代码允许我的哲学家尝试抓住他们需要一起用餐的两个叉子。

    // if the forks are locked then start eating
    if (result == -1)
    {
        state[j] = philosophers::State::Eating;
        eating[j]++;
        if (longestWait < waiting[j])
        {
            longestWait = waiting[j];
        }
        waiting[j] = 0;
    } else {
        state[j] = philosophers::State::Thinking;
        thinking[j]++;
        waiting[j]++;
    }

the above code monitors my philosophers progress eating or thinking depending if they manage to reserve the two forks. 上面的代码监视我的哲学家进食或思考的进度,这取决于他们是否设法保留了两个叉子。

    {
        testEnd te(eating[j]+thinking[j]-1);
        unique_lock<mutex> lk(cycleDone);
        endCycle.wait(lk, te);
    }

the above code waits for all the philosophers to complete the selection after this time the philosopher is free to make a new attempt: 在这段时间之后,上面的代码等待所有哲学家完成选择,哲学家可以自由地进行新的尝试:

    if ( philosophers::State::Eating == state[j] )
    {
        state[j] = philosophers::State::Thinking;
        forks[lhf].unlock();
        forks[rhf].unlock();
    }

I have a main thread that monitors the philosophers and moves them from one cycle to the next that allows them about 10 seconds to eat and think as much as they can. 我有一个主线程来监视哲学家,并将他们从一个周期转移到下一个周期,这使他们可以吃大约10秒钟的时间,并尽可能多地思考。 The result is about 9540 cycles with some philosophers starving and other having plenty to eat and lots of thinking time! 结果是大约9540个循环,其中一些哲学家挨饿,而另一些哲学家则需要大量食物和思考时间! So I need to protect my philosophers from starvation and waiting too long so I add more logic to prevent over eating by requiring the eating philosophers to release and think rather than gab the same forks after a very small break: 因此,我需要保护我的哲学家免于饥饿和等待太久,因此我通过要求进餐哲学家在很小的休息后松开并思考而不是用相同的叉子来思考,从而增加了更多的逻辑来防止过度进食:

    // protect the philosopher against starvation
    if (State::Thinking == previous)
    {
        result = try_lock(forks[lhf], forks[rhf]);
    }

Now I have 9598 cycles with every philosopher getting a relatively equal share of eating (2620 - 2681) and thinking with the longest wait of 14. Not bad. 现在我有9598个周期,每个哲学家都获得相对相等的进餐份额(2620-2681),并以最长的等待时间14进行思考。 But I am not satisfied so now I get rid of all the mutex's and locks and keep it simple with the even philosophers eating in even cycles and the odd philosophers eating in odd cycles. 但是我不满意,所以现在我摆脱了所有的互斥锁和锁,并使偶数哲学家在偶数周期中进食而奇数哲学家在奇数周期中进食使它变得简单。 I use a simple method of syncing the philosophers 我使用一种简单的方法来同步哲学家

while (counter < counters[j])
{
    this_thread::yield();
}

Prevents a philosopher from eating or thinking too many times using a global cycle counter. 使用全局周期计数器防止哲学家进食或思考过多次。 Same time period and the philosophers manage about 73543 cycles with 36400 eating and no more than 3 cycles waiting. 在相同的时间段内,哲学家管理着约73543个周期和36400次进餐,等待的周期不超过3个周期。 So my simple algorithm with no locks is both faster and has a better distribution of processing between the various threads. 因此,我没有锁的简单算法既速度更快,又在各个线程之间具有更好的处理分配。

Can anyone think of a better way to solve this problem? 谁能想到解决这个问题的更好方法? I fear that when I implement a complex system with multiple threads that if I follow traditional mutex and message passing techniques I will end up with slower than necessary and possible unbalanced processing on the various threads in my system. 我担心当我实现一个具有多个线程的复杂系统时,如果我遵循传统的互斥锁和消息传递技术,最终将导致系统中各个线程的处理速度比必要的慢,并且可能导致处理不平衡。

This is an interesting way to explore the issues of threading in c++. 这是探索c ++中线程问题的一种有趣方式。

To address specific points: 解决特定问题:

I fear that when I implement a complex system with multiple threads that if I follow traditional mutex and message passing techniques I will end up with slower than necessary and possible unbalanced processing on the various threads in my system. 我担心当我实现一个具有多个线程的复杂系统时,如果我遵循传统的互斥锁和消息传递技术,最终将导致系统中各个线程的处理速度比必要的慢,并且可能导致处理不平衡。

Unfortunately, the best answer I can give you is that this is a well founded fear. 不幸的是,我能给你的最好的答案是,这是有充分根据的恐惧。 The cost of scheduling and synchronization is very specific to the application, though -- this becomes an engineering decision when designing a large system. 调度和同步的成本是针对应用程序的,这非常特殊-在设计大型系统时,这成为工程决策。 First and foremost, scheduling is NP-Hard ( http://en.wikipedia.org/wiki/Multiprocessor_scheduling ) but has good approximations. 首先,调度是NP-Hard( http://en.wikipedia.org/wiki/Multiprocessor_scheduling ),但是具有良好的近似性。

As far as your particular example, I think it is difficult to draw general conclusions based on the results you present -- there is one primary take home point: the trade off between coarse grain synchronization and fine grain synchronization. 就您的特定示例而言,我认为很难根据您呈现的结果得出一般性结论-有一个主要的认识点:粗粒度同步与细粒度同步之间的权衡。 This is well studied problem and some research may be helpful (eg http://ieeexplore.ieee.org/xpls/abs_all.jsp?arnumber=744377&tag=1 ). 这是一个经过充分研究的问题,有些研究可能会有所帮助(例如, http : //ieeexplore.ieee.org/xpls/abs_all.jsp?arnumber=744377&tag=1 )。

Overall, this touches on a engineering issue which is going to be specific to the problem you want to solve, the operating system and the hardware. 总体而言,这涉及到一个工程问题,该问题将特定于您要解决的问题,操作系统和硬件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM