OpenMP:同时写入std::map

OpenMP: writing into std::map concurrently

本文关键字:std map OpenMP      更新时间:2023-10-16

我有一个std::map,键与thread_num相同。每个线程都在向值中写入std::vector。因此保证了每个线程仅在"他的"CCD_ 3上操作。

示例:

#include <iostream>
#include <omp.h>
#include <map>
#include <vector>

int main(void) {
    std::map<unsigned int, std::vector<unsigned int> > M;
// initialize map using first touch policy:
#pragma omp parallel for schedule(static,1)
    for (int i=0; i<omp_get_num_procs(); ++i) {
#pragma omp critical
        M[omp_get_thread_num()] = std::vector<unsigned int>();
    }
// do some parallel operations:
#pragma omp parallel for schedule(static)
    for (int i=0; i<100; ++i) {
        M[omp_get_thread_num()].push_back(i);
    }
// disp the content:
    for (auto it_key : M) {
        std::cout << "thread " << it_key.first << " : {";
        for (auto it_vec : it_key.second) {
            std::cout << it_vec << " ";
        }
        std::cout << "b b}" << std::endl;
    }
    return 0;
}

输出看起来如所需。问题是上述守则是否合法?所以我可以得出结论,我可以并行地操作std::map,只要我可以保证只有一个线程在操作特定密钥的辅助数据?

您的第二个循环看起来不错,因为您没有修改映射本身,而是只修改键下的值。来自

http://www.cplusplus.com/reference/map/map/operator[]/

数据竞赛容器被访问,并且可能被修改。该函数访问一个元素并返回一个可用于修改其映射值的引用同时访问其他元素是安全的如果函数插入一个新元素,那么在容器中同时迭代范围是不安全的。

第一个循环可能最好不要同时进行,因为无论如何这都是最少的工作量——在一个线程中进行,然后再进行syn_threads。按照标准,它现在的方式似乎不安全,只是碰巧适用于您的配置

编辑

事实上,由于在第一个循环中,您不访问其他元素,而只是插入新的元素,所以按照标准,这也是安全的,尽管同时进行并没有任何好处。