ошибка при обработке и редактировании Qmap внутри цикла OpenMP - PullRequest
0 голосов
/ 04 апреля 2019

Я делаю цикл для с openmp в c ++ для подачи некоторых значений в QMAP из QVector, и на некоторых компьютерах он говорит, что «программа перестала работать», но на некоторых компьютерах это работает.

Я видел, что Qmap не является потокобезопасным, однако мне нужен контейнер с тегами (из-за этого я использую Qmap) для ввода результатов внутреннего вычисления и использования его позже в последовательной части кода.

пример моего кода следующий: Бытие mystringlist a QString, themaps - это QMap<QString, QMap<int, QVector<float>>> и 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]; 
       }
    }
}

в последовательном режиме этот код работает, однако в параллельном блоке иногда происходит сбой. Поэтому я думаю, что если есть метод, позволяющий всем потокам обрабатывать эти переменные карты, чтобы он не падал, потому что они не будут пытаться записывать в одно и то же пространство памяти, каждый из них имеет свой собственный i, так что они должны иметь возможность сделать это , Я не знаю другого варианта сделать это, потому что мне нужно использовать эту переменную themaps позже в коде.

1 Ответ

1 голос
/ 05 апреля 2019

Разумное решение: защитите ваши общие переменные с помощью мьютекса . Вы, конечно, платите за это снижение производительности, что допустимо только в том случае, если вычисление нового значения занимает намного больше времени, чем вставка в структуру данных.

Смелое решение: предварительно распределить все поля, чтобы структура данных не изменилась из-за вставок.

Вам нужно учесть два эффекта:

  1. Если вы получите доступ к ключу QMap, который не существует, будет создано новое поле. Карта отсоединится. Это изменит внутреннюю структуру данных.
  2. Если вы обращаетесь к карте неконстантным методом, карта также отсоединится, если у вас есть более одной ссылки на нее (идиома копирования Qt при записи).

Для QVector это просто с QVector::resize(n). После этого вы можете установить любое значение поля в пределах [0..n-1], если никто не читает и не пишет в это поле одновременно.

QMap - это другой зверь. Избегайте, если возможно.
(Подсказка: только итераторы гарантируют, что не вернут копию элемента.)

...