首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >c++:自旋锁或互斥比较(简单计算)

c++:自旋锁或互斥比较(简单计算)
EN

Stack Overflow用户
提问于 2015-04-05 02:02:29
回答 1查看 1.4K关注 0票数 1

对于简单的任务,自旋锁应该比互斥锁具有更好的性能。但是,在这个简单的测试(增加计数器的8个线程)中,结果显示了不同的结果:

代码语言:javascript
运行
复制
#include <iostream>
#include <thread>
#include <mutex>
#include <atomic>
#include <vector>

using namespace std;

class SpinLock {
private:
    atomic_flag lck = ATOMIC_FLAG_INIT;
public:
    void lock() { while(lck.test_and_set(memory_order_acquire)) {} }
    void unlock() { lck.clear(memory_order_release); }
};

int total = 0;

#ifdef SPINLOCK
SpinLock my_lock;
#else
mutex my_lock;
#endif

void foo(int n)
{
    for(int i = 0; i < 10000000; ++i) {
#ifdef SPINLOCK
        lock_guard<SpinLock> lck(my_lock);
#else
        lock_guard<mutex> lck(my_lock);
#endif
        ++total;
    }
}

int main()
{
    vector<thread> v;

    for(int i = 0; i < 8; ++i)
        v.emplace_back(foo, i);

    for(auto& t : v)
        t.join();

    cout << "total: " << total << endl;
    return 0;
}

测试自旋锁:

代码语言:javascript
运行
复制
$ g++ -DSPINLOCK -std=c++11 -Wall -pthread test.cc
$ time ./a.out
total: 80000000
real    0m18.206s
user    2m17.792s
sys     0m0.003s

要测试互斥对象:

代码语言:javascript
运行
复制
$ g++ -std=c++11 -Wall -pthread test.cc
$ time ./a.out
total: 80000000
real    0m9.483s
user    0m6.451s
sys     1m6.043s

结果表明,互斥锁比自旋锁快近两倍。自旋锁在“用户cpu”中花费的时间最多,而互斥锁在"sys cpu“中花费的时间最多。互斥锁是如何实现的?在这样的简单计算中,我应该使用互斥锁而不是自旋锁吗?有人能解释一下结果吗?

g++为4.8.2,操作系统为RedHatEnterpriseLinux7。

谢谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-04-05 02:39:19

一些注意事项:

  1. time实用程序输出中显示的时间是线程使用的CPU时间,而不是实际时间。Spinlock甚至在等待期间也使用cpu,而内核互斥将在等待时在其他进程中执行其他线程,除了用于实际执行调度的进程(在互斥对象情况下在sys行中看到的进程)之外,不为该CPU时间计费您的进程。
  2. 由于上述相同的原因,在spinlock情况下,从进程开始到结束所需的总等待时间可能更快,但是cpu的使用率可能更高,这就是您观察到的。
  3. 如果您有较低的冲突机会,那么线程处理可能是一个很好的选择,即与异步负载相比,线程在同步负载上花费的时间较少。如果您的所有负载都是由互斥保护的,那么在使用线程时就只会产生开销--您可能应该序列化它。

旋转锁是好的,如果你有较低的碰撞机会和较低的等待时间,以防止碰撞。在您的示例中,有8个线程与同一资源发生冲突,然后要求资源在释放后立即可用。这意味着平均将有一个线程工作和其他7个自旋锁定,使总的CPU时间是单线程所需时间的8倍(如果您有一个8核心机器,并且没有其他负载)。在互斥锁中,线程只在资源可用时暂停并唤醒,因此没有等待的开销,但是锁定互斥量将需要一些开销,这是内核中要做的工作,以跟踪哪些进程正在等待互斥量,即使不太大,也要执行1.6亿个互斥锁操作,这些操作总计到向进程发出的sys时间。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29453377

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档