百科问答小站 logo
百科问答小站 font logo



如何设计真正高性能的 spin_lock? 第1页

  

user avatar   skywind3000 网友的相关建议: 
      

应用层用spinlock的最大问题是不能跟kernel一样的关中断(cli/sti),假设并发稍微多点,线程1在lock之后unlock之前发生了时钟中断,一段时间后才会被切回来调用unlock,那么这段时间中另一个调用lock的线程不就得空跑while了?这才是最浪费cpu时间的地方。所以不能关中断就只能sleep了,怎么着都存在巨大的冲突代价。

尤其是多核的时候,假设 Kernel 中任务1跑在 cpu1上,任务 2跑在 cpu2上,任务1进入lock之前就把中断关闭了,不会被切走,调用unlock的时候,不会花费多少时间,cpu2上的任务2在那循环也只会空跑几个指令周期。

看看 Kernel 的 spinlock:

                #define _spin_lock_irq(lock)           do {            local_irq_disable();            preempt_disable();            _raw_spin_lock(lock);            __acquire(lock);           } while (0)             

看到里面的 local_irq_disable() 了么?实现如下:

        #define local_irq_disable()  __asm__ __volatile__("cli": : :"memory")       

倘若不关闭中断,任务1在进入临界区的时候被切换走了,50ms以后才能被切换回来,即使原来临界区的代码只需要0.001ms就跑完了,可cpu2上的任务2还会在while那里干耗50ms,所以不能禁止中断的话只能用 sleep来避免空跑while浪费性能。

所以不能关闭中断的应用层 spinlock 是残废的,nop都没大用。

不要觉得mutex有多慢,现在的 mutex实现,都带 CAS,首先会在应用层检测冲突,没冲突的话根本不会不会切换到内核态,直接用户态就搞定了,即时有冲突也会先尝试spinlock一样的 try 几次(有限次数),不行再进入休眠队列。比傻傻 while 下去强多了。




  

相关话题

  C++ STL中的map用红黑树实现,搜索效率是O(lgN),为什么不像python一样用散列表从而获得常数级搜索效率呢? 
  如何理解编程语言中「流」(stream)的概念? 
  怎样理解C++中“如果属性有在堆区开辟的,一定要自己提供拷贝构造函数,防止浅拷贝带来的问题”? 
  如何才能写出没有bug的程序? 
  求助:C++中应该怎样理解实参和形参的区别? 
  想走虚幻引擎c++路线,c++是否应该大量学习算法? 
  有没有什么程序库使得我们可以比较方便的在windows下使用比较新版本的opengl的? 
  C++ 的 string 为什么不提供 split 函数? 
  如何设计真正高性能的 spin_lock? 
  C++中delete this是对象先析构还是delete语句先返回? 

前一个讨论
如果一个程序员工作5年后还没成为大牛,是不是该考虑别的路子了?
下一个讨论
进体制是普通人规避中年危机的最佳方式吗?





© 2025-01-31 - tinynew.org. All Rights Reserved.
© 2025-01-31 - tinynew.org. 保留所有权利