【问题标题】:Fastest KV data structures for merging unique keys?用于合并唯一键的最快 KV 数据结构?
【发布时间】:2013-06-09 21:21:50
【问题描述】:

我目前有大约 15 个工作线程在 CPU 密集型循环中处理数据。每次确定结果时,都会获得一个 RW 锁,因此可以将结果存储在一个共享的 KV 结构(哈希表)中,键唯一。

由于花费了很多时间来获取锁,我正在探索不同的选项来提高性能。我玩过无锁哈希表(concurrent_unordered_map 和英特尔 TBB 无锁结构),但一直想知道让每个线程将其结果记录在单独的哈希表中,并且一旦所有线程完成,执行某种冲突解决。

冲突解决基本上是针对每个 [K1,V1], [K1,V2], .... [K1,Vn] 应该合并为 [K1,F(V1,V2,...Vn) ]。

我很好奇哪种数据结构最适合从其他结构迭代相同键的所有值。我确信必须有比单独迭代每个结构更好的东西。创建多图,批量添加单独的结构,然后解决冲突等?

【问题讨论】:

  • 我假设在当前方法中,在每次插入之前都会进行唯一性测试。如果每个线程使用一个哈希表,您将如何维护唯一键?或者键是否自动都是唯一的?
  • 密钥是正在处理的数据的派生属性,因此它已经存在。唯一性检查是这样的,结果可以按所述键分组。

标签: algorithm data-structures merge data-processing


【解决方案1】:

使用允许您直接访问其支持数组的哈希表,并为每个线程的哈希表使用相同大小的支持数组。然后当需要合并哈希表时,在工作线程之间划分支持数组 - 例如,有 15 个工作线程并假设支持数组大小为 1500,worker_thread_1 将从 [0, 100),worker_thread_2 将从 [100, 200) 等遍历每个哈希表的后备数组。这样,每个工作线程都可以执行其合并,而无需获取任何锁或以任何其他方式与其他工作线程通信。直接迭代后备数组会带来一些低效率,因为一些数组元素将为空(可能有 10-50% 的元素将为空,具体取决于您的哈希表的负载因子),但同时通过直接迭代您不需要执行散列函数的后备数组,它应该弥补遍历空元素的低效率。

您需要为每个线程的哈希表使用相同大小的后备数组,以确保每个键散列到相同的数组元素(尽管在划分子数组时可能有一种方法可以纠正不同大小的后备数组您的工作线程 - 我只是想不出一个合适的算法。

您还需要使用使用链表进行冲突的哈希表 - 使用冲突探测的哈希表会使事情变得过于复杂。

您可以通过使用有序映射(例如平衡二叉树或跳过列表)并在工作线程之间平均分配键来完成同样的事情,但这不会那么有效,因为您将使用 O(log(n)) 插入和查找,而不是使用哈希表的恒定时间(平均)插入和查找。

【讨论】:

  • 非常有趣的方法!我喜欢支持数组作为哈希表和数组的双重用途,以及同时在多个线程上解决冲突的能力。
猜你喜欢
  • 1970-01-01
  • 2011-03-18
  • 1970-01-01
  • 2015-05-22
  • 2018-11-03
  • 1970-01-01
  • 2011-04-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多