Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenMP: writing into std::map concurrently

Tags:

c++

c++11

openmp

i have a std::map with the key being identical to the thread_num. each thread is writing into the value, a std::vector here. hence it is guaranteed that each thread is only operating on "his" std::vector.

Example:

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

the output looks as desired. the question would be whether the above code is legal? so i can conclude that i can operate on a std::map in parallel, as long as i can guarantee that only one thread is operating on the secondary data of a specific key?

like image 966
the_ducky Avatar asked Sep 14 '25 06:09

the_ducky


1 Answers

Your second loop looks fine, since you are not modifying the map itself, but only value under the key. From

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

Data races The container is accessed, and potentially modified. The function accesses an element and returns a reference that can be used to modify its mapped value. Concurrently accessing other elements is safe. If the function inserts a new element, concurrently iterating ranges in the container is not safe.

First loop probably better to do not concurrently, since it is minimal amount of work anyways - do it in one thread and syn_threads afterwards. The way it is now seems not safe by the standard, just happen to work on your configuration.

EDIT

Actually, since in first loop you are not accessing other elements but just inserting new ones, it is safe by the standard too, although there is no benefit of doing it concurrently.

like image 175
Ilya Kobelevskiy Avatar answered Sep 16 '25 20:09

Ilya Kobelevskiy