Я столкнулся с распараллеливанием алгоритма, который в своей последовательной реализации исследует шесть граней куба, состоящего из местоположений массива в гораздо большем трехмерном массиве. (То есть, выберите элемента массива, а затем определить куб или прямоугольную параллелепипед вокруг этого элемента 'n' элементов, удаленных по x, y и z, ограниченных границами массива.
Каждая рабочая единица выглядит примерно так (псевдокод Фортрана; серийный Алгоритм написан на Фортране):
do n1=nlo,nhi
do o1=olo,ohi
if (somecondition(n1,o1) .eq. .TRUE.) then
retval =.TRUE.
RETURN
endif
end do
end do
Или псевдокод C:
for (n1=nlo,n1<=nhi,n++) {
for (o1=olo,o1<=ohi,o++) {
if(somecondition(n1,o1)!=0) {
return (bool)true;
}
}
}
В общем алгоритме есть шесть таких рабочих блоков, где значения «lo» и «hi» обычно находятся в диапазоне от 10 до 300.
Что я думаю, было бы лучше всего запланировать шесть или более потоков выполнения, циклически, если ядер ЦП не так много, в идеале с циклами, выполняющимися параллельно, с той же целью, что и последовательный алгоритм: какое-то условие ()
становится True
, выполнение всех потоков должно быть немедленно остановлено, и значение True
установлен в общем месте.
Какие методы существуют в компиляторе Windows для облегчения распараллеливания таких задач? Очевидно, что мне нужен главный поток, ожидающий семафора или завершения рабочих потоков, поэтому необходимо вложение и сигнализация, но мой опыт работы с OpenMP на этом этапе является вводным.
Существуют ли в OpenMP механизмы передачи сообщений?
РЕДАКТИРОВАТЬ: Если наибольшая разница между «nlo» и «nhi» или «olo» и «ohi» составляет от восьми до десяти, это будет означать не более 64–100 итераций для этого вложенного цикла и не более 384. до 600 итераций для шести рабочих единиц вместе. Исходя из этого, стоит ли вообще распараллеливать?