c - 自定义共享 HashMap 实现

标签 c algorithm hash hashmap

我见过很多共享的 hashmap 实现。这是我试图解决的具体情况。

我正在尝试在多处理器系统中进行层次聚类。假设我在“n”个处理器中运行“n”个线程。令输入总数为 K。在第一次迭代中,我们必须找到所有对 (k^2) 之间的距离并将它们存储在 HashMap 中。为了实现此多线程,我将每个处理器 (K^2/n) 个输入对分配给处理。

现在距离结果必须存储在某种 HashMap 中以供下一次迭代使用。每个处理器还输出它找到的最小距离。合并所有处理器中距离最小的对。

在下一次迭代中,我们需要找到这个新合并的对与所有其他 (k-2) 个输入的距离。并将这些新距离与已存储在哈希表中的所有其他对的距离进行比较。

由于哈希表上存在并发写入,因此使用带锁的单个哈希表会有效地消除并行性。

系统的一个要求是,每个线程都不会得到上次得到的相同对。因此它必须读取自己和其他线程生成的哈希值以找到已经存储的距离。

于是我有了以下想法:

    -Each thread has its own hash table and has access to the hash table of other threads.
    -Iteration -1 : No read is performed this time since the hash tables are empty.  So each thread just writes to its own hash table.
    -Iterations 2 : Each thread is going to generate some new pairs.  But for all the other old pairs it needs to read the hash_maps to find the distance (might be its own hash_map or the hash_map of other threads).
    -Iterations 3 to k-1 : Same as iteration 2.

为了提高从迭代 2 到 k-1 的并行性,我设计了以下想法:

            - store the newly generated values in a new hashmap.
            - for old values keep reading the old hash_maps.  Since concurrent reads can be done, this phase is completely parallel.
            - for each entry in the new hash_map
                      find the which threads's hashmap has this entry.  Replace the old value by the new value.  This step might be effectively sequential because we have to both read and write at the same time.

这是一个可以有效实现的想法吗?如果您对如何改进这一点有任何建议,请告诉我。特别是对于第三步——这是整个想法的瓶颈。如果有一个有效的实现可以实现此步骤的最大并行度,那就太好了。

我使用来自 google 的稀疏哈希库作为 hash_map。

最佳答案

因此,实现此目的的一种方法是只使用一个分桶 HashMap ——有 N 个映射,每个映射存储具有 0 mod n、1 mod n 等哈希的键。然后,您只需要锁定第 n 个 HashMap 一次。由于您希望读取比写入更常见,因此您可以对读取使用共享锁,对写入使用独占锁,这将进一步降低您的争用。

您还可以有一个“洗牌步骤”,而不是每个线程写入它计算的值,每个线程负责对特定存储桶的所有写入。线程将首先将新值写入对应于哈希表桶的队列(您可以通过各种竞争最小化方式进行),然后每个线程将使用一个队列并在一个大的中执行对其单个哈希表的所有写入去——无争用。

关于c - 自定义共享 HashMap 实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9929419/

相关文章:

algorithm - 二分查找插入排序

java - 使用 HashMap 读取/写入 txt 文件 - 小修复

python - 从 Flash 客户端验证文件真实性而不泄露 key

c++ - 如何将 std::hash 专门化为来自其他库的类型

c - 0 在 socket() 系统调用中表示什么?

c++ - 奇怪的算法性能

algorithm - LZW-解压缩算法

通过将字符串传递给函数使用 strtok 分割标记时代码崩溃

c - 如何创建一个函数将输出保存到文本文件?

c - 将 fftw3 与 fftw 复杂类型一起使用