Closed
Description
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:
- Is
sparse_matrix[key].fetch_add(val)
, as shown above, safe? Or should I precompute every key and preallocate the map with 0s usinginsert
(isinsert
oremplace
safer)? - Do I need
std::atomic
or issparse_matrix[key] += val
safe?