为什么sleep_for(纳秒(1))在繁忙等待循环中如此提高性能?

时间:2015-10-30 05:20:02

标签: c++ multithreading

问题

在实现一个简单的信号量时,我试图计算在忙等待循环中花费的平均时间,并以纳秒为单位休眠这段时间。无论哪种方式,睡眠1纳秒似乎都可以达到同样的效果:当我打电话时,速度会快速增加(大约快6倍)...

std::this_thread::sleep_for(std::chrono::nanoseconds(1));

...在信号量的P()函数的忙等待循环中。

我相信睡眠会大大减少争用,但我希望有更多知识渊博的人给我一个更确定的答案。

使用std::this_thread::yield();比简单的自动锁定更有利于执行时间,但仍然具有较高的CPU使用率(90-100%)。睡眠方法使其保持在10-15%;线程仍然是交错的,因此并不是一个线程连续执行其所有指令。

代码

我尽可能地将此示例最小化以突出显示代码的相关部分。我在问题的最后提供了一个完整实现的演示链接。

#include <atomic>
struct semaphore
{
public:
    explicit semaphore( int const max_concurrency );

    void P()
    {
        // why does this sleep improve performance so much?
        while ( !try_decrease_count() )
            std::this_thread::sleep_for( std::chrono::nanoseconds( 1 ) );
    }

    void V()
    {
        count_.fetch_add( 1 );
    }

private:
    bool try_decrease_count();

    std::atomic<int> count_;
};

semaphore::semaphore( int const max_count )
    : count_{ max_count }
{}

bool semaphore::try_decrease_count()
{
    int old_count{ count_.load() };
    do
    {
        if ( !old_count ) return false;
    } while ( !count_.compare_exchange_strong( old_count, old_count - 1 ) );
    return true;
}

演示

这些包括完整的代码和测试。

使用sleep_for进行演示:http://coliru.stacked-crooked.com/a/ff16411d9a884556

没有sleep_for的演示:http://coliru.stacked-crooked.com/a/2df776f0a03425b1

0 个答案:

没有答案