- 论坛徽章:
- 9
|
本帖最后由 wlmqgzm 于 2017-02-13 02:56 编辑
不存在race condition, 详细解释如下:
不管内部循环是什么代码, 由于最终起作用的指令还是第1条指令, d_atomic_bool.exchange( true, std::memory_order_acquire ), 因此不存在race condition.
// 这里第1行 d_atomic_bool.load( std::memory_order_relaxed 是写模式,每次都要独占cache,并且将其他CPU的cache设置为invalide, 第1行改为 cas 指令也一样有内存写预占争用.
// 如果两个以上CPU在等待这把锁,将交替将64字节内存反复同步, 数据冲突激烈,影响其他线程的内存操作,降低整体性能, 是影响的全部CPU的工作效率, 因为产生了内存争用, 产生了总线争用
while( d_atomic_bool.exchange( true, std::memory_order_acquire ) ) {
// 下面的指令主要是为了减少CAS指令循环对内存总线带来的不良影响, 尤其是目前CPU核心数量越来越多的情况, 下列循环只有在锁被释放后, 才会跳出循环, 但是这个指令消耗的资源要极少,
// 很多人没有认识到CAS指令的代价高得惊人, 那么, 为了将代价减少到极致, 我们就增加了下面这组指令来解决问题,
// 增加下面这组指令是 只读模式检查, 只需要锁没有被释放, 这里继续循环, 但是这组spin是没有竞争状态的, 不会对内存和cache产生任何影响, 只要锁不释放, 永远不会内存总线的争夺, 因此提高了整体的效率
while( d_atomic_bool.load( std::memory_order_relaxed ) ) {
yield();
continue;
}
// 当 d_atomic_bool 的锁被释放后, 执行存在内存冲突的CAS指令/exchange指令, 这样在多数情况下, 就不存在多个CPU因为CAS指令造成内存总线长期被无效内容占用, 整体CPU效率大幅度下滑的情况出现.
// 不管内部循环是什么代码, 由于最终起作用的指令还是第1条指令, d_atomic_bool.exchange( true, std::memory_order_acquire ), 因此不存在race condition.
continue;
}
另外, 你的开源软件中spin_lock也是用 exchange , 因为这个指令比cas效率高, cas指令也是要预占读写权限的, 与exchange没有区别,
//
// spinlock.hpp
// fibio
//
// Created by Chen Xu on 14-6-20.
// Copyright (c) 2014 0d0a.com. All rights reserved.
//
#ifndef fibio_fibers_detail_spinlock_hpp
#define fibio_fibers_detail_spinlock_hpp
#include <atomic>
namespace fibio { namespace fibers { namespace detail {
/**
* class spinlock
*
* A spinlock meets C++11 BasicLockable concept
*/
class spinlock {
private:
typedef enum {Locked, Unlocked} LockState;
std::atomic<LockState> state_;
public:
/// Constructor
spinlock() noexcept : state_(Unlocked) {}
/// Blocks until a lock can be obtained for the current execution agent.
void lock() noexcept {
while (state_.exchange(Locked, std::memory_order_acquire) == Locked) {
/* busy-wait */
}
}
/// Releases the lock held by the execution agent.
void unlock() noexcept {
state_.store(Unlocked, std::memory_order_release);
}
};
}}} // End of namespace fibio::fibers::detail
#endif
关于锁, 前一段时间研究比较多, 在公司里重写基本库, 基本上把各类锁都用最新的思路重新写了一遍, 看的资料也比较多, 核心概念上不会犯错误的.
|
|