用于合并唯一键的最快的KV数据结构?

时间:2013-06-09 21:21:51

标签: algorithm data-structures merge data-processing

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

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

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

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

1 个答案:

答案 0 :(得分:1)

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

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

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

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