• Log in
Anwen  Share and Create
  • Book
  • Movies
  • Music
  • SF
  • Goodlink
  • Asks
  • Eyeopen
  • Create

Folly 的 MicroSpinLock 使用方法和实现

Sharer: 阅微堂 December 30, 2019 at 11:00 pm
Link Share :https://zhiqiang.org/coding/folly-micro-spinlock.html - via RSS

由 Facebook 开发和维护的 C++库 Folly 提供了自旋锁的实现folly::MicroSpinLock,代码文件地址:https://github.com/facebook/folly/blob/master/folly/synchronization/MicroSpinLock.h。

folly::MicroSpinLock小到只有一个字节,并且为POD类型,也就是说它可以保存到文件,在(共享)内存中共享!

根据 Facebook 的测试,该自旋锁单次耗时约 13.5ns ,std::mutex性能大约在 25ns ,参考的虚函数单次调用耗时约 1.7ns。

它的使用很简单,就是lock和unlock函数,也可以用std::lock_guard来自动上锁和解锁(folly提供MSLGuard的typedef):

folly::MicroSpinLock spinlock; 

spinlock.lock();
// your work need to protect
spinlock.unlock();

{
    // 已定义typedef std::lock_guard<MicroSpinLock> MSLGuard  
    MSLGuard guard{spinlock};
    // your work need to protect
}

为了达到POD的目的,folly::MicroSpinLock只有一个uint8_t类型的成员lock_。但每次使用时,会强行转换成std::atomic对象:

std::atomic<uint8_t>* payload() noexcept {
    return reinterpret_cast<std::atomic<uint8_t>*>(&this->lock_);
}

我们细看lock的实现:

void lock() noexcept {
  detail::Sleeper sleeper;
  while (!cas(FREE, LOCKED)) {
    do {
      sleeper.wait();
    } while (payload()->load(std::memory_order_relaxed) == LOCKED);
  }
  assert(payload()->load() == LOCKED);
  annotate_rwlock_acquired(
      this, annotate_rwlock_level::wrlock, __FILE__, __LINE__);
}

这里面有三个地方需要展开说。

第一个是cas,这个是std::atomic提供的标准比较替换的原子实现:

bool cas(uint8_t compare, uint8_t newVal) noexcept {
  return std::atomic_compare_exchange_strong_explicit(
      payload(),
      &compare,
      newVal,
      std::memory_order_acquire,
      std::memory_order_relaxed);
}

这里用了对内存顺序要求最高的std::atomic_compare_exchange_strong_explicit。具体原因和对效率的影响不太清楚。

第二个是用了detail::Sleeper。最终实现了,前 4000 次检查失败时,会插入_mm_pause空指令,但 4000 次之后,将休眠 0.5 毫秒,此时将让出 CPU ,线程被切换,避免总是占住 CPU。

因为每次只插入一条pause空指令,所以 4000 次检查,不一定够。但不提供修改方式(除了改源代码)。

第三个是最后还调用了annotate_rwlock_acquired这个函数。这个用于配合线程检查工具ThreadSanitizer,检查多线程编程中是否有Data Race现象。

当用户没有开启选项时,该函数会被编译器优化掉,因此不用担心该行代码会降低性能。

作者暂无likerid, 赞赏暂由本网站代持,当作者有likerid后会全部转账给作者(我们会尽力而为)。

Tips: Until now, everytime you want to store your article, we will help you store it in Filecoin network. In the future, you can store it in Filecoin network using your own filecoin.


Support author:
Author's Filecoin address:
Or you can use Likecoin to support author:
tags:编程 folly 自旋锁 多线程编程 C++

0 0

2012-2018 Anwen All of our posts are default licensed under CC BY 4.0 About Help Changelog Telegram
Today Quote: 手段的不纯洁,必然导致目的的不纯洁。 -- 甘地