Folly 的 MicroLock 使用方法和实现

作者: , 共 694 字 , 共阅读 0

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

folly::MicroLock小到只有一个字节,并且为POD类型。

根据 Facebook 的测试,该锁单次耗时约 27ns ,略高于std::mutex的 25ns ,参考的虚函数单次调用耗时约 1.7ns。不过既然还慢于std::mutex,那么MicroLock存在的价值是什么呢?

它的价值在于它很小,小到只有一个字节,却可以提供 4 个锁。每个锁占用 2 个位。如果只用最开头的一个锁,那么它可以小到 2 个位,这样可以共享其它数据的低位,比如指针(由于数据按 4 位对齐,对于大多数指针的末两位都是 0 ):

union Pointer {
  folly::MicroLock lock;
  void* _ptr;

  void* get_ptr() const {
    return _ptr & ~(3);
  }

  void set_ptr(void* ptr) {
    _ptr = ptr | (_ptr & 3);
  }

  void lock() {
    lock.lock();
  }

  void unlock() {
    lock.unlock();
  }
}

为什么一个锁需要两个位,还没看明白。似乎是一个位保存hold状态,另一个位保存wait状态。

Q. E. D.

类似文章:
由 Facebook 开发和维护的 C++库 Folly 提供了自旋锁的实现folly::MicroSpinLock,代码文件地址:https://github.com/facebook/folly/blob/master/folly/synchronization/MicroSpinLock.h
看到网上有片段,提到没有必要自己实现自旋锁,因为标准库的 std::mutex 和现在的自旋锁的实现没有两样。比较好奇,翻了一些资料,试图找到答案。
编程 » folly, C++, 数据容器
由 Facebook 开发和维护的 C++库 Folly 提供folly::sorted_vector_setfolly::sorted_vector_map,是std::mapstd::set在小数据集上的优化版。代码见: https://github.com/facebook/folly/blob/master/folly/sorted_vector_types.h
编程 » C++, folly
folly::fbstring是一个完全兼容std::string的类,可以做到无缝替换,而且性能更高。其代码参见https://github.com/facebook/folly/blob/master/folly/FBString.h
编程 » C++, 智能指针
理论上而言,当 C++提供了std::unique_ptr, C++的程序就不应该出现普通指针了。所有普通指针都可以用std::unique_ptr代替,避免手动删除对象。
编程 » folly, C++, 数据容器
由 Facebook 开发和维护的 C++库 Folly 提供folly::small_vector,代码文件地址:https://github.com/facebook/folly/blob/master/folly/small_vector.h
编程 » C++, folly
高效程序总是尽量避免频繁触碰在堆上分配和释放内存,所以无论是std::string还是folly:fbstring都做了SSO( small string optimization )。而folly::FixedString是一个很有意思的实现,它可以把任意长度的字符串都放在堆上。代码可见https://github.com/facebook/folly/blob/master/folly/FixedString.h
智能指针在现代 C++里用得越多。以前只知道它大致的原理,比如使用引用计数。但很多实现细节并不清楚,最直接的,它是如何实现多线程安全的?今天找了 gnu c++ library 的实现好好看了一下。
编程 » C++, Boost, 智能指针
如果理解了侵入式容器,侵入式智能指针也很容易理解。传统的智能指针std::shared_ptr使用了和数据无关的引用计数,这带来两个问题:
编程 » C++, C++标准库
std::tuple的原理并不复杂,但有些细节非常有意思。其中有一个是至少在gnu C++ std的实现中,std::tuple是倒序存储的:
编程 » C++, folly
高效程序总是尽量避免频繁触碰在堆上分配和释放内存,所以无论是std::string还是folly:fbstring都做了SSO( small string optimization )。而folly::FixedString是一个很有意思的实现,它可以把任意长度的字符串都放在堆上。代码可见https://github.com/facebook/folly/blob/master/folly/FixedString.h