Skip to content

Is concurrent_map[key].fetch_add(val) thread safe? #1591

Closed
@carlos-souto

Description

@carlos-souto

For example, consider this code to build a sparse matrix in the coordinate format:

using TKey = std::pair<size_t, size_t>;
using TVal = std::atomic<double>;

tbb::concurrent_map<TKey, TVal> sparse_matrix;

tbb::parallel_for(i_start, i_stop, [&](size_t i) {
    // some computation for the i-th index is performed, resulting in a key and a corresponding value
    // key may or may not have been computed before

    // update map
    sparse_matrix[key].fetch_add(val); // is this thread safe?
});

Although rare, two threads may need to fetch/insert the same key and update the corresponding value.

My understanding is that, if the key does not exist, concurrent_map ensures safe insertion, and if the key does exist concurrent_map ensures safe lookup. std::atomic<T>::fetch_add ensures the value itself is updated safely.

My questions:

  1. Is sparse_matrix[key].fetch_add(val), as shown above, safe? Or should I precompute every key and preallocate the map with 0s using insert (is insert or emplace safer)?
  2. Do I need std::atomic or is sparse_matrix[key] += val safe?

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions