I am doing a loop for with openmp in c++ to feed some values inside a QMAP from a QVector and in some computers it says "program stopped to work" but in some computers it works.
I saw that Qmap is not thread safe however I need a container with tags (because of that I use a Qmap) to input the results from an inside calculation and use it later in a serial part of the code.
an example of my code is as follows: Being mystringlist
a QString
, themaps
is a QMap<QString, QMap<int, QVector<float>>>
and myvector
a QVector<float>
.
#pragma omp parallel for schedule(static) num_threads(std::thread::hardware_concurrency())
for (int i = 0; i < numb_of_iter; i++)
{
for each (auto var in mystringlist)
{
for (int j = 0; j < 33; j++)
{
themaps[var][i] << std::log10(j+1) + myvector[i];
}
}
}
in serial mode this code works, however in a parallel block sometimes it crashes. So my idea is if there is a method to allow all threads to acess this variable themaps so it wont crash because they wont try to write in the same memory space, each one has its own i
so they should be able to do that. I do not know another option to do that because I need to use this variable themaps
later on the code.
The sane solution: Protect your shared variables via a mutex. You of course pay a performance penalty for that, which is only acceptable if the calculation of the new value takes much longer than the insertion into your data structure.
The bold solution: Preallocate all fields so that the data structure doesn't change because of the insertions.
You'd need to consider two effects:
QMap
key that doesn't exist, a new field will be created. The map will detach. This will change the internal data layout.For QVector
, that's simple with QVector::resize(n)
. After this, you can set any field value within [0..n-1] as long as no one else reads or writes to that field at the same time.
QMap
is a different beast. Avoid, if possible.
(Just a hint: Only the iterators guarantee not to return a copy of the item.)