更新OpenMP for循环中的哈希映射

时间:2017-05-01 20:44:36

标签: c++ multithreading openmp

我正在尝试使用openmp进行for循环,我试图插入/更新哈希映射(std::unordered_map

哈希映射和键实际上是类的成员,因此我指定了表示其地址的指针.Key也是全局函数返回的哈希值。

以下似乎是最简单的方法,但哈希映射未正确更新。有些东西是错的,但我不确定如何解决。谢谢。

void MyClass::ProcessBuffer(void)
{
    omp_set_num_threads(4);
    std::unordered_map<unsigned long long,unsigned int>* hashptr=&m_sequencehash;
    std::vector<std::string>* bufferptr=&m_buffer;
    unsigned int sizevec=m_kmer_size;
    size_t i;
    #pragma omp parallel for
    for (i=0; i<READSTR_BUF_SIZE;++i)
    {
        ++(*hashptr)[_hash((*bufferptr)[i],sizevec)];
    }

}

1 个答案:

答案 0 :(得分:1)

解决此问题的最简单方法是为每个线程创建一个新映射,然后按顺序将它们缩减为单个映射。这是一个经典的map-reduce方案。

int s = omp_get_num_threads();
std::unordered_map<unsigned long long,unsigned int> res[s];

// Map step
#pragma omp parallel for
for (i=0; i<READSTR_BUF_SIZE;++i)
{
    int t = omp_get_thread_num();
    res[t][_hash((*bufferptr)[i],sizevec)]++;
}

// Reduce step
for (int i=0; i < s; i++) {
    for (auto r : res[s]) {
        (*hashptr)[r.first] += r.second;
    }
}

同时执行缩减可能很危险,因为您仍然必须同时访问同一个映射。如果您不了解地图的实施情况,则无法确定这是否安全。

或者,您可以通过将不同的哈希间隔放在不同的存储区中来对不同映射之间的哈希值进行分区。这将防止不同的线程在reduce步骤中访问相同的哈希值。但是,在小型数据集上,很难找到具有少量存储桶的良好分区功能。与串行approch相比,使用太多存储桶可能会产生很大的开销。