前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Swisstable:C++中比std::unordered_map更快的hash表

Swisstable:C++中比std::unordered_map更快的hash表

原创
作者头像
ahfu_zhang
发布2022-06-23 15:00:43
1.4K0
发布2022-06-23 15:00:43
举报
文章被收录于专栏:算法优化

这个算法由google开源,最早在2017年的c++大会上分享过。

文章概览

效果

hash表的实现,实在是太经典太没什么新意了,但是这个数据结构又是用得太多太基础的组件了,如果有人能够把hashtable做的更快,实在也没理由拒绝。Google实现的这个hash表的性能,请看下图:

(图片引用了Zhihu 流左沙文章内图片)

各种情况下,swisstable比std::unordered_set至少快两倍!!!

低负载情况

高负载情况

找到的情况

快2倍以上

快6倍

找不到的情况

快2.5倍

快6倍

对比std::unordered_map

hash表通常号称O(1)的时间复杂度,但是在hash冲突存在的情况下,往往达不到O(1)的时间复杂度。

众所周知(我最喜欢问的面试题),解决hash冲突有以下经典的三种方式:

  • 开放地址法
  • 相邻地址法
  • 多散列函数法

重点在于,std::unordered_map使用开放地址法来解决hash冲突。

链表最大的问题就在于——在当代的CPU架构下,内存比SSD快100倍,而cpu cache又比内存快100倍,链表对于CPU cache并不友好。因此,cache友好的结构能够提升性能。

关键设计

Swiss table的关键设计就是——通过相邻地址法来解决hash冲突。一个平坦的内存结构,能够提高cpu cache命中率。

因此,具体的设计细节,都是针对相邻地址法解决hash冲突的具体办法。

大致结构

swiss hash的大致结构可以表述如下:

代码语言:javascript
复制
 struct Item{
     uint64_t hashcode;  //57bit
     void* key;
     void* value;
 };
 ​
 #define MAX_ITEMS 1024  /*hash的长度以2的幂对齐*/
 ​
 struct SwissTable{
     Item items[MAX_ITEMS];
     uint8_t meta_table[MAX_ITEMS];  //元数据表,用于解决hash冲突
 };
 ​

hashcode

通过在key上执行hash函数,得到一个64位的hash值。

把hash值分为高7位和低57位:

  • 低57位用于定位桶中slot的位置
  • 高7位用于在control byte中解决hash冲突

control byte

hash桶中每个slot对应一个1一个byte的控制字节。

Control byte的高1位用于表示状态,低7位用于存储hashcode的高7位。

状态位分为:

  • 未使用:0xFF表示(全为1)
  • 已删除:0x80表示(最高位为1,其余位为0)
  • 在使用:0x00~0x7F之间的值(最高位为1)

group概念

以128bit对齐的连续8字节的control byte称为一个group。

解决hash冲突通常在slot对应的control byte所在的group内解决。

以128bit对齐的原因是,group内的搜索,可以用四条SIMD指令来解决。

展望

  • 搜索了一下,目前还没有golang版本的swiss table,后续准备实现一个
  • Flat hashtable不仅仅只是CPU CACHE友好,这样的结构配合原子操作,相信很容易做出一个并发版本的hash table。后续也准备在这里做一些尝试。
  • 算法的优化进入深水区了:
    • 与当下的CPU架构结合起来,很多经典算法能够老树开新花
    • 假设当前使用的是苹果的M1芯片,那么经典算法可能在异构计算的体系里产生更多令人惊异的提升。

参考文章

google开源的abseil库

源码

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章概览
  • 效果
  • 对比std::unordered_map
  • 关键设计
    • 大致结构
      • hashcode
        • control byte
          • group概念
          • 展望
          • 参考文章
            • google开源的abseil库
              • 源码
              相关产品与服务
              GPU 云服务器
              GPU 云服务器(Cloud GPU Service,GPU)是提供 GPU 算力的弹性计算服务,具有超强的并行计算能力,作为 IaaS 层的尖兵利器,服务于生成式AI,自动驾驶,深度学习训练、科学计算、图形图像处理、视频编解码等场景。腾讯云随时提供触手可得的算力,有效缓解您的计算压力,提升业务效率与竞争力。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档