Мне нужна помощь по следующей проблеме:
результат моих вычислений сохраняется в массиве, который разделяется между потоками OMP. Поскольку я не знаю, сколько записей будет иметь мой конечный результат, мне нужно динамически расширять, то есть освобождать / перераспределять его, что может происходить только последовательно. Я хотел бы избегать проверки размера каждый раз, когда используется критический OMP, поскольку это сильно замедляет код и только при наличии достаточных результатов массив результатов необходимо снова расширять.
Поэтому я пришел к выводу следующий код, который, однако, мне не очень нравится (но он выполняет свою работу):
if (resCnt> curAlloc) then
!$OMP CRITICAL
if (resCnt> curAlloc) then
allocate(results_temp(1:resCnt+allocationStep))
results_temp(1:resCnt) = results
call MOVE_ALLOC(results_temp, results)
curAlloc = curAlloc+allocationStep
end if
!$OMP END CRITICAL
end if
Идея кода, приведенного выше, состояла в том, чтобы сначала проверить переменную, которая все еще находится в параллельном контексте. Если затем один поток обнаруживает, что требуется «перераспределение», он сначала должен проверить снова, однако в критическом контексте. Как только один поток завершит критическую область, другие заметят, что условие для роста больше не нужно, и также выйдут из критической области.
Есть ли ошибка в моем мышлении выше или лучше: есть ли более простой способ справиться с ростом массива? Если это интересно: тип массива - это пользовательский тип, и я могу получить результаты, скажем, от 1.000 до 10.000.000 (в будущем эта верхняя граница может больше не сохраняться).
Любой совет приветствуется. Спасибо!