OpenMP: использование модифицированной переменной
real(8) :: A(1000 B(1000)
real(8) :: tmp
!$omp parallel private(tmp)
do i = 1, 1000
tmp = 10 * i
B(i) = tmp
A(i) = A(i) + tmp
enddo
Понятно что несколько через задницу, но зато работать будет
Ситуация такая, что есть примерно следующая структура:
CYCLE_1
CYCLE_2
....
CYCLE_N
где CYCLE_i - некий цикл, имеющий следующую структуру
DO I = I_LEFT, I_RIGHT
.....
END FOR
Хочется определить I_LEFT и I_RIGHT для каждого треда и получить
!$OMP PARALLEL
CYCLE_1
...
CYCLE_N
!$OMP PARALLEL END
При этом не надо просматривать каждый цикл.
Проверил сейчас на сишном коде и gcc-шном openmp - код как в первом посте работает как надо.
Так что можно проверить конкретную реализацию и забить.
Что-то мне подсказывает, что в когда я с ним работал на это забивал и без особых последствий
upd
icc 11.1 тоже работает нормально
Почему в стандартном случае мы можем присвоить переменной a значение 10, а потом использовать ее,
а в случае с тредами нет?
Хотел бы уточнить еще пару вопросов:
1. Правильно ли я понимаю, что можно преспокойно использовать
MPI-функции внутри всех создаваемых тредов?
2. Допустим есть существующий кусок кода
INTEGER REQ
INTEGER DEST
...
MPI_ISEND(DEST, REQ)
MPI_WAITALL(1, REQ)
где DEST какой-то номер вычислительного узла, соответсвенно на DEST делается
MPI_IRECV(SRC, REQ)
MPI_WAITALL(1, REQ)
и узлы обмениваются информацией.
Допустим теперь эти два узла стали на самом деле тредами в одном mpi-процессе.
То есть теперь эти два треда исполняют тот же код, где SRC и DEST есть ранг того
узла, где эти треды исполняются. Можно ли оставлять такой код без изменений?
Честно говоря MPI уже не помню, но я бы не рискнул делать такое смешение технологий. OpenMP это все-таки технология для SMP, а MPI для кластеров, плюс MPI с тем же успехом ложится на SMP. В общем не видно необходимости сочетать эти технологии.
Мы реализовали MPI-версию некоторой программы.
Далее хочется использовать то, что каждый вычислительный узел
имеет 4 ядра, а потому можно воспользоваться дополнительным
преимуществом в виде тредов на каждом вычислительном узле.
Самым простым решением было бы обойти каждый цикл и сделать
!$OMP DO/!$OMP END DO. К сожалению из-за специфики задачи такой
вариант явно не оптимальный, а более продвинутый вариант
предполагает некий обмен м/у областями, отсюда и пробема, касающаяся
вопроса 2.
MPI должен уметь запускаться на SMP безо всяких дополнительных выкрутасов.
MPI-программа запускается на MPI-кластере - все как обычно.
Но каждый вычислительный узел имеет 4 ядра, поэтому можно
для каждого MPI-процесса запустить эффективно еще 4 треда.
Ну не то, чтобы прямо спокойно (см MPI_Init_thread, например). Но race condition'ов в самом MPI не будет, главное самому дополнительных не навести (делать tag уникальным, например).
Не-не все ясно. Я к тому, что MPI должен сам уметь порождать потоки на многоядерных нодах, причем обмен между потоками на одной ноде может происходить через прямое копирование памяти или через сетевой интерфейс на выбор.
Оставить комментарий
kataich
Я новичок в OpenMP. Помогите разрешить следующий вопрос.Здесь, на странице 11 в самом конце написано:
Как обходить такую проблему в случае, если я не хочу обращаться к данным, за которые ответственен другой тред,
а только к своим данным ( как в случае выше)?
Очевидное решение, разбить цикл выше на два, где сначала инициализируется массив B, а затем изменяется массив
A. К сожалению, к моему случаю такой вариант не подходит в виду огромного количества таких циклов. Можно ли это исправить как-нибудь по-другому?