c ++中线程的性能11

Pet*_*ete 8 c++ concurrency c++11

我对使用基于pthreads和Ubuntu开发环境的线程的最新gcc中的互斥和消息传递的性能感兴趣.一个很好的通用问题是餐饮哲学家,每个哲学家都使用lh和rh fork与左手和右手邻居共享.我将哲学家的数量增加到99,以保持我的四核处理器繁忙.

    int result = try_lock(forks[lhf], forks[rhf]);
Run Code Online (Sandbox Code Playgroud)

上面的代码允许我的哲学家试图抓住他们需要吃的两把叉子.

    // 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]++;
    }
Run Code Online (Sandbox Code Playgroud)

上面的代码监视我的哲学家进步吃或思考取决于他们是否设法保留两把叉子.

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

在这段时间之后,上述代码等待所有哲学家完成选择,哲学家可以自由地进行新的尝试:

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

我有一个主线程,监视哲学家,并将他们从一个周期移动到下一个周期,让他们大约10秒吃,并尽可能多地思考.结果是大约9540个周期,一些哲学家挨饿,其他人有足够的食物和大量的思考时间!因此,我需要保护我的哲学家免于饥饿和等待太久,所以我增加了更多的逻辑来防止过度饮食,要求饮食哲学家释放和思考,而不是在经过一个小小的休息后抓住相同的叉子:

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

现在我有9598个周期,每个哲学家的饮食份额相对平等(2620 - 2681)并且考虑最长的等待时间14.不错.但是我并不满足所以现在我摆脱了所有的互斥锁和锁定,并且让偶数哲学家在偶数周期中吃东西并且奇怪的哲学家在奇怪的周期中吃东西时保持简单.我用一种简单的方法来同化哲学家

while (counter < counters[j])
{
    this_thread::yield();
}
Run Code Online (Sandbox Code Playgroud)

使用全局循环计数器防止哲学家吃东西或思考太多次.同一时期,哲学家管理大约73543个周期,吃36400个,等待不超过3个周期.所以我的没有锁的简单算法既快又更好,并且在各种线程之间有更好的处理分配.

谁能想到更好的方法来解决这个问题?我担心当我实现一个具有多个线程的复杂系统时,如果我遵循传统的互斥和消息传递技术,我将最终在系统中的各个线程上执行速度慢于必要且可能的不平衡处理.

haz*_*dev 2

这是探索 C++ 中线程问题的有趣方法。

解决具体问题:

我担心,当我实现一个具有多个线程的复杂系统时,如果我遵循传统的互斥体和消息传递技术,我最终会导致系统中各个线程的处理速度比必要的慢,并且可能会出现不平衡的处理。

不幸的是,我能给你的最好答案是,这是一种有根据的恐惧。不过,调度和同步的成本对于应用程序来说是非常特定的——在设计大型系统时,这成为一个工程决策。首先也是最重要的,调度是 NP-Hard ( http://en.wikipedia.org/wiki/Multiprocessor_scheduling ),但具有很好的近似值。

就您的特定示例而言,我认为根据您提供的结果很难得出一般性结论 - 有一个主要要点:粗粒同步和细粒同步之间的权衡。这是一个经过充分研究的问题,一些研究可能会有所帮助(例如http://ieeexplore.ieee.org/xpls/abs_all.jsp?arnumber=744377&tag=1)。

总的来说,这涉及到一个工程问题,该问题将特定于您想要解决的问题、操作系统和硬件。