Я столкнулся с распараллеливанием алгоритма, который в своей последовательной реализации проверяет шесть граней куба мест расположения массива в гораздо большем трехмерном массиве. (То есть выберите элемент массива, а затем определите куб или кубоид вокруг этого элемента 'n' элементов, удаленных по x, y и z, ограниченных границами массива.
Каждая рабочая единица выглядит примерно так (псевдокод Fortran; последовательный алгоритм в Fortran):
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.
Я думаю, что лучше всего было бы запланировать шесть или более потоков выполнения, циклически, если не так много ядер ЦП, в идеале с циклами, выполняющимися параллельно, с целью, аналогичной последовательному алгоритму. : somecondition()
становится True
, выполнение среди всех потоков должно быть немедленно остановлено, и значение True
устанавливается в общей папке.
Какие методы существуют в компиляторе Windows для облегчения распараллеливания таких задач? Очевидно, что мне нужен главный поток, который ожидает семафор или завершение рабочих потоков, поэтому существует необходимость во вложении и передаче сигналов, но мой опыт работы с OpenMP является вводным на данном этапе.
Существуют ли механизмы передачи сообщений в OpenMP?
РЕДАКТИРОВАТЬ: Если наибольшая разница между "nlo" и "nhi" или "olo" и "ohi" составляет от восьми до десяти, это будет означать не более 64-100 итераций для этого вложенного цикла и не более 384 до 600 итераций для шести рабочих блоков вместе. Исходя из этого, стоит ли вообще распараллеливать?