Большинство реализаций OpenMP (с некоторыми умными исключениями) делают то же самое - они выделяют каждую параллельную область в отдельной функции, а затем запускают ее в нескольких потоках.
PROGRAM Parallel_Ordered_Hello
USE OMP_LIB
INTEGER :: thread_id, j
j = 0
!$OMP PARALLEL PRIVATE(thread_id) SHARED(j)
thread_id = OMP_GET_THREAD_NUM()
DO i=0,OMP_GET_MAX_THREADS()
PRINT *, "Hello from process: ", thread_id
END DO
!$OMP ATOMIC UPDATE
j = j + thread_id
!$OMP END PARALLEL
END
становится чем-то вроде
PROGRAM Parallel_Ordered_Hello
USE OMP_LIB
TYPE omp_data
INTEGER, POINTER :: j
END TYPE
INTEGER :: thread_id
INTEGER, TARGET :: j
TYPE(omp_data) :: omp_shared_data
j = 0
omp_shared_data%j => j
CALL _libomp_parallel(omp_func1, omp_shared_data)
END
SUBROUTINE omp_func1(omp_shared_data)
USE OMP_LIB
TYPE(omp_data) :: omp_shared_data
INTEGER :: thread_id, i
thread_id = OMP_GET_THREAD_NUM()
DO i=0,OMP_GET_MAX_THREADS()
PRINT *, "Hello from process: ", thread_id
END DO
CALL _libomp_atomic_increment(omp_shared_data%j, thread_id)
END SUBROUTINE
Я немного увеличил сложность, добавив общую переменную, просто чтобы показать, как обрабатываются такие переменные. omp_func1
- это выделенное содержимое параллельной области. Она выполняется в нескольких потоках при вызове _libomp_parallel()
(это не настоящая функция, а просто макет). Потоки выполняются одновременно, и нет абсолютно никакой гарантии относительно порядка, в котором они отображаются. gfortran
принимают опцию -fdump-tree-all
, которая заставляет их выгружать промежуточное представление кода на разных этапах компиляции в текстовые файлы, по одному для каждого этапа. Код похож на C и несколько труден для чтения, но он дает отличное понимание того, как G CC обрабатывает OpenMP. Особый интерес представляют файлы .omplower
и .ompexp
.
Обратите внимание, что в приведенном вами примере есть два случая неявных определений относительно i
. Во-первых, его тип неявно определяется как INTEGER
из его имени (начинается с i
). Во-вторых, его атрибут совместного использования данных OpenMP предварительно определен как PRIVATE
в соответствии с правилом, согласно которому последовательные l oop переменные являются частными в самой внутренней параллельной области или конструкции, создающей задачу. В целом это плохая практика программирования. Используйте и IMPLICIT NONE
, чтобы запретить автоматическую c типизацию Fortran, и DEFAULT(none)
, чтобы запретить автоматические c правила атрибутов совместного использования данных OpenMP.
Кстати, сообщение должно фактически читать «Здравствуйте от резьба ... ".