更新OpenMP内部的哈希地图以进行循环

Update a hash map inside OpenMP for loop

本文关键字:循环 地图 哈希 OpenMP 内部 更新      更新时间:2023-10-16

我正在尝试将OpenMP用于for循环,我正在尝试插入/更新哈希地图(std::unordered_map(

哈希地图和密钥实际上是一类的成员,因此我分配了指针代表其地址。关键也是全局函数返回的哈希值。

以下方法似乎是最简单的方法,但是哈希地图未正确更新。某件事是/错误的,但我不确定如何解决。谢谢。

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)];
    }
}

解决此问题的最简单方法是为每个线程创建一个新的地图,然后将它们依次将其缩小为单个映射。这是一个经典的地图降低场景。

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;
    }
}

同时执行还原可能是危险的,因为您仍然必须同时访问同一地图。如果您不知道地图的实现,则无法确定这是安全的。

另外,您可以通过将不同的哈希间隔放入不同的存储桶中来分配不同映射之间的哈希值。这将防止不同的线程在减少步骤中访问相同的哈希值。但是,在一个小数据集上,很难找到具有少量存储桶的良好分区功能。与串行批准相比,使用太多的水桶可能具有明显的间接费用。