揭秘Facebook官方底层C++函数Folly

一曲冷凌霜 提交于 2019-12-05 02:02:41

Folly与Boost、当然还有std等组件库的关系是互为补充,而不是彼此竞争。实际上,只有当我们需要的东西既没有,也无法满足所需的性能要求时,我们才开始定义自己的组件。

性能问题贯穿着Folly的大部分,有时导致比较具有特质性的设计(比如PackedSyncPtr.h和SmallLocks.h)。整体上确保良好的性能是所有Folly的统一主题。

逻辑设计

Folly是一组相对独立的组件的集合体,有些组件就是几个符号这么简单。内部依赖方面没有限制,这意味着某个特定的folly模块可以使用其他任何的folly组件。

所有符号都在顶层的命名空间folly中加以定义,当然除了宏。宏名称是ALL_UPPERCASE。命名空间folly定义了其他的内部命名空间,比如internal或detail。用户代码应该不依赖那些命名空间中的符号。

物理设计

在顶层,Folly采用经典的“结巴”(stuttering)方案folly/folly,这也是Boost及其他组件库所采用的。第一个目录充当库的安装根目录(可能是以folly-1.0/这样的形式);第二个目录是添加文件时用来辨别组件库,比如#include "folly/FBString.h"。

目录结构是扁平的(模仿命名空间结构),也就是说我们没有复杂的目录层次结构(这个情况在将来的版本中可能会有变化)。子目录experimental含有在folly里面使用的文件,可能用在Facebook端,但是被认为不够稳定,无法在客户端使用。你的代码不该使用folly/experimental中的文件,以免你在更新Folly时,出现问题。

folly/folly/test子目录包括了面向所有组件的单元测试,通常名为ComponentXyzTest.cpp,面向每个ComponentXyz.*。folly/folly/docs目录含有说明文档。

兼容性

目前,folly已在64位安装版Fedora 17、Ubuntu 12.04和Debian wheezy的gcc 4.6上进行了测试。它不用改动,就可以在其他64位Linux平台上运行。

组件

下面按字母顺序介绍了一系列Folly组件,另外附有每个组件的简短描述。

Arena.h,ThreadCachedArena.h

内存分配的简单地方:多次内存分配同时被释放。使用线程版本。

AtomicHashMap.h,AtomicHashArray.h

高性能的原子哈希图,采用几乎无锁的操作。

Benchmark.h

用于代码基准测试的小型框架。客户端代码注册基准测试,可选情况下使用一个变量来规定基准测试的范围(迭代和工作集大小等)。框架运行基准测试(受制于命令行标记),生成带计时信息的格式化输出。

Bits.h

各种位处理实用组件,针对速度而优化。

Bits.h

位变换函数,使用统一接口包装ffsl(l)图元。

ConcurrentSkipList.h

实现了用证实正确的可扩展并发跳跃表(Provably Correct Scalable Concurrent Skip List)描述的结构,这种跳跃表由Herlihy及其他人共同开发。

Conv.h

各种数据转换例程(尤其是to和from字符串),针对速度和安全进行了优化。

DiscriminatedPtr.h

类似boost::variant,但完全局限于指针。使用指针中最高位、未使用的16位作为鉴别器。所以sizeof(DiscriminatedPtr<int, string, Widget>) == sizeof(void*)。

dynamic.h

动态类型对象,创建时关注JSON对象。

Endian.h

Endian转换图元。

Escape.h

以C方式转义字符串。

eventfd.h

针对eventfd系统调用的包装器。

FBString.h

嵌入式实现std::string,进行了诸多优化。

FBVector.h

基本上嵌入式实现std::vector,进行了诸多优化。

Foreach.h

伪语句(作为宏语句来实现),用于迭代。

Format.h

Python式样的格式化实用组件。

GroupVarint.h

针对32位值的Group Varint编码。

Hash.h

各种流行的哈希函数实现。

Histogram.h

一个简单的类,用于收集直方图数据。

IntrusiveList.h

方便类型定义,用于使用boost::intrusive_list。

json.h

JSON序列化器和反序列化器。使用dynamic.h。

Likely.h

针对__builtin_expect的包装器。

Malloc.h

内存分配助手,尤其是使用jemalloc时。

MapUtil.h

一种助手,用于查找联合容器中的项目(比如std::map和std::unordered_map)。

PackedSyncPtr.h

一种高度专业化的数据结构,含有指针、1位旋转锁和15位整数,它们都在一个64位单词中。

Preprocessor.h

不好但又必不可少的组件。

PrettyPrint.h

针对数字的美化打印组件,用于添加所用单元的后缀:字节(kb、MB等)、度量单位后缀(k、M和G等)以及时间(s、ms、us和ns等)。

ProducerConsumerQueue.h

无锁单读取器单写入器队列。

Random.h

只定义了一个函数:randomNumberSeed()。

Range.h

Boost式样的范围工具和StringPiece专门化。

RWSpinLock.h

快速而紧凑的读取器/写入器旋转锁。

ScopeGuard.h

老式ScopeGuard用语的C++11版本。

SmallLocks.h

非常小的旋转锁(1字节和1位)。

small_vector.h

一种向量,含有小缓冲器方面的优化和可选的嵌入式PicoSpinLock。

sorted_vector_types.h

类似std::map的集合体,但是作为排序向量来实现。

StlAllocator.h

标准模板库(STL分配器),包装简单的分配/取消分配接口。

String.h

连接folly::fbstring和std::string的字符串实用组件。

Synchronized.h

高级同步库。

System.h

解码和errno实用组件。

ThreadCachedInt.h

使用线程缓存的高性能原子增量。

ThreadLocal.h

经过改进的线程本地存储,用于存储非平凡类型。

TimeoutQueue.h

按项目设定超时的队列。

Traits.h

类型特性,补充了在标准的C++11头<traits>中定义的那些类型特性。

Unicode.h

定义了codePointToUtf8函数。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!