Презентацию к лекции Вы можете скачать здесь.
Auto-parallelization функция компилятора Intel® автоматически переводящая последовательные части программы в эквивалентный многопоточный код.
Последовательный код
subroutine serial(a, b, c)
integer, dimension(100) :: a, b, c
do i = 1,100
a(i) = a(i) + b(i) * c(i)
enddo
end subroutine serial
Параллельный код
subroutine sub_par(a, b, c)
integer, dimension(100) :: a, b, c
do i = 1,50 ! поток 1
a(i) = a(i) + b(i) * c(i)
end do
do i = 51,100 ! поток 2
a(i) = a(i) + b(i) * c(i)
end do
end subroutine par
Критерии параллелизации цикла
do
! вычисления
if (условие) exit
end do
FLOW, READ after WRITE)ANTI, WRITE after READ)OUTPUT, WRITE after WRITE)Директива !DEC$ PARALLEL приводит к параллельному выполнению цикла.
!DEC$ PARALLEL [ALWAYS]
выполнять параллельно, даже если это противоречит "решению" компилятора.
!DEC$ PARALLEL [ALWAYS [ASSERT]]
выдавать сообщение о невозможности распараллеливания цикла
!DEC$ NOPARALLEL
отмена автопараллелизации
Пример использование директив !DEC$ PARALLEL, !DEC$ NOPARALLEL
program prog
integer, parameter :: n = 100
integer x(n),a(n)
!DEC$ NOPARALLEL
do i = 1,n
x(i) = i
end do
!DEC$ PARALLEL
do i = 1,n
a( x(i) ) = i
end do
end
Организация параллельного выполнения цикла. Не должно быть зависимости по данным.
real Q
do concurrent (k = 1:N)
Q = B(k) + C(k)
D(k) = Q + sin(Q) + 2
end do
CAF (CoArray Fortran) середина 90-х годов
Поддержка компанией Cray. Центр развития – Rice University
Модель PGAS (Partitioned Global Address Space) разделённое глобальное адресное пространство.
Глобальная адресуемая память представлена логическими разделами. У каждого процессора свой раздел.
Архитектура SPMD "Single program multiple data" ("Одна программа - много данных")
Создаётся один экземпляр программы, который затем копируется несколько раз. Каждая копия выполняется параллельно, обрабатывает свои локальные данные.
Данные распределенные между копиями программы объявляются как coarray переменные.
В свойствах проекта указать использование Coarrays, при необходимости Coarray Images.
Image - копия CAF - программы.
Функция num_images() возвращает количество созданных копий программы.
Количество копий программы как правило соответствует количеству имеющихся процессоров. В общем случае устанавливается в настройках проекта.
Каждая копия имеет свой уникальный номер, возвращаемый функцией this_image().
Данные распределенные между images объявляются как coarray переменные.
тип имя [*]
integer A[*] ! A[1] – переменная A
! в копии № 1
! A[2] – переменная A
в копии № 2
real С(N)[-1:*] ! С(N)[-1] – массив С
! в копии № 1
! С(N)[0] – массив С
! в копии № 2
complex Y(50)[1:10,1:*]
type (matrix) MS[*]
real, allocatable :: W(:)[:]
Пересылка данных – обращение к элементам coarrays.
complex C(100,100)[*]
Объявление копии массива для всех images.
C(1:10,30:50)[2] = C(21:30,90:100)[3]
Пересылка сечения массива из 3-й копии во 2-ю.
Если без скобок то обращение к локальному, т.е. в первой копии программы пересылка массива А в k-ю копию A[k] = A равносильно A[k] = A[1]
Для определения номера копии программы по индексам coarray используется функция image_index().
program CAF
complex Y(50)[1,1:*]
if (this_image() == 1) then ! == 2
write(*,*) "This is ", this_image(),
" copy of program "
write(*,*) "Image index = ",
image_index(Y, [1,this_image()])
write(*,*) "Coordinates = ", this_image(Y)
write(*,*)
end if
This is 1 copy of program
Image index = 1
Coordinates = 1 1
Функция lcobound возвращает нижнюю границу coarray - переменной. Функция ucobound возвращает верхнюю границу coarray - переменной.
type point
integer x
integer y
end type point
type (point) PS(10)[1,-2:*]
! num_images() = 4 ! 1 -2
write(*,*) "LCOBOUND = ", LCOBOUND (PS)
write(*,*) "UCOBOUND = ", UCOBOUND (PS)
! 1 1
Всем images установить значения переменных.
Две копии программы рисующие разные случайные геометрические фигуры. Первая – прямоугольники, Вторая – окружности.
Вариант программы
program prog2
use ifqwin
integer, parameter :: dx = 10, dy = 10
do
call random_number(x); call random_number(y)
call random_number(r); call random_number(g)
call random_number(b)
ires2 = setcolorrgb(rgbtointeger(int(r*255),
int(g*255),
int(b*255)))
if (this_image() == 1) ires2 = rectangle(3,int2(x*800),
int2(y*600),int2(x*800)+dx, int2(y*600)+dy)
if (this_image() == 2) ires2 = ellipse(3,int2(x*800),
int2(y*600),int2(x*800)+dx, int2(y*600)+dy)
end do
end
Барьерная синхронизация. Копии программы приостанавливаются на барьере до тех пор, пока на барьере не окажутся все копии программы.
program CAF
integer, parameter :: M = 100
real A(M,M)[*]
if (this_image() == 1) then
call random_number(A)
A = real(int(A*10))
do k = 2,num_images() ! каждый узнал об изменении
A[k] = A
end do
end if
sync all
...
integer :: i, k1, k2
integer(8) sum = 0, k[*] ! k - coarray-переменная
if (this_image() == 1) then ! --- план для вычислений
k1 = 1; k2 = 100
end if
if (this_image() == 2) then
k1 = 101; k2 = 100000
end if
do i = k1,k2 ! --- расчет каждой копией программы
k[this_image()] = k[this_image()] + i
end do
SYNC ALL ! дожидаемся всех, сколько каждая копия насчитала
if (this_image() == 1) then ! --- сбор результатов
do i = 1,num_images()
sum = sum + k[i]
end do
write(*,*) sum ! 5000050000
end if
end
SYNC IMAGES(image_set)
Синхронизация избранных копий программы,
image_set |
– массив номеров копий программы или просто номер копии |
image_set(*) |
- означает все копии |
if (this_image() == 5) then
! image 5 ожидает других images,
! чтобы завершить использование данных.
sync images(*)
else
sync images(5)
! Другие images ожидают image 5,
! чтобы установить данные,
! но не ожидают никакого другого image.
end if
critical
! операторы, выполняемые в любой момент
! времени только одной копией программы
end critical
program CAF
implicit none
complex Y(50)[1,1:*]
write(*,*) "This is ", this_image(), " copy of program "
write(*,*) "Image index = ", image_index(Y,[1,this_image()])
write(*,*) "Coordinates = ", this_image(Y)
write(*,*)
end program CAF
This is 1 copy of program
This is 2 copy of program
Index = 2
Coordinates = 1 2
Index = 1
Coordinates = 1 1
This is 2 copy of program
This is 1 copy of program
Index = 2
Coordinates = 1 2
Index = 1
Coordinates = 1 1
This is 2 copy of program
This is 1 copy of program
Index = 1
Coordinates = 1 1
Index = 2
Coordinates = 1 2
Экран – критическая секция.
program CAF
implicit none
complex Y(50)[1,1:*]
critical
write(*,*) "This is ", this_image(), " copy of program "
write(*,*) "Image index = ", image_index(Y,[1,this_image()])
write(*,*) "Coordinates = ", this_image(Y)
write(*,*)
end critical
end program CAF
This is 1 copy of program
Image index = 1
Coordinates = 1 1
This is 2 copy of program
Image index = 2
Coordinates = 1 2
Написать программу нахождения максимума в одномерном массиве.
Презентацию к лекции Вы можете скачать здесь.
Auto-parallelization функция компилятора Intel® автоматически переводящая последовательные части программы в эквивалентный многопоточный код.
Последовательный код
subroutine serial(a, b, c)
integer, dimension(100) :: a, b, c
do i = 1,100
a(i) = a(i) + b(i) * c(i)
enddo
end subroutine serial
Параллельный код
subroutine sub_par(a, b, c)
integer, dimension(100) :: a, b, c
do i = 1,50 ! поток 1
a(i) = a(i) + b(i) * c(i)
end do
do i = 51,100 ! поток 2
a(i) = a(i) + b(i) * c(i)
end do
end subroutine par
Критерии параллелизации цикла
do
! вычисления
if (условие) exit
end do
FLOW, READ after WRITE)ANTI, WRITE after READ)OUTPUT, WRITE after WRITE)Директива !DEC$ PARALLEL приводит к параллельному выполнению цикла.
!DEC$ PARALLEL [ALWAYS]
выполнять параллельно, даже если это противоречит "решению" компилятора.
!DEC$ PARALLEL [ALWAYS [ASSERT]]
выдавать сообщение о невозможности распараллеливания цикла
!DEC$ NOPARALLEL
отмена автопараллелизации
Пример использование директив !DEC$ PARALLEL, !DEC$ NOPARALLEL
program prog
integer, parameter :: n = 100
integer x(n),a(n)
!DEC$ NOPARALLEL
do i = 1,n
x(i) = i
end do
!DEC$ PARALLEL
do i = 1,n
a( x(i) ) = i
end do
end
Организация параллельного выполнения цикла. Не должно быть зависимости по данным.
real Q
do concurrent (k = 1:N)
Q = B(k) + C(k)
D(k) = Q + sin(Q) + 2
end do
CAF (CoArray Fortran) середина 90-х годов
Поддержка компанией Cray. Центр развития – Rice University
Модель PGAS (Partitioned Global Address Space) разделённое глобальное адресное пространство.
Глобальная адресуемая память представлена логическими разделами. У каждого процессора свой раздел.
Архитектура SPMD "Single program multiple data" ("Одна программа - много данных")
Создаётся один экземпляр программы, который затем копируется несколько раз. Каждая копия выполняется параллельно, обрабатывает свои локальные данные.
Данные распределенные между копиями программы объявляются как coarray переменные.
В свойствах проекта указать использование Coarrays, при необходимости Coarray Images.
Image - копия CAF - программы.
Функция num_images() возвращает количество созданных копий программы.
Количество копий программы как правило соответствует количеству имеющихся процессоров. В общем случае устанавливается в настройках проекта.
Каждая копия имеет свой уникальный номер, возвращаемый функцией this_image().
Данные распределенные между images объявляются как coarray переменные.
тип имя [*]
integer A[*] ! A[1] – переменная A
! в копии № 1
! A[2] – переменная A
в копии № 2
real С(N)[-1:*] ! С(N)[-1] – массив С
! в копии № 1
! С(N)[0] – массив С
! в копии № 2
complex Y(50)[1:10,1:*]
type (matrix) MS[*]
real, allocatable :: W(:)[:]
Пересылка данных – обращение к элементам coarrays.
complex C(100,100)[*]
Объявление копии массива для всех images.
C(1:10,30:50)[2] = C(21:30,90:100)[3]
Пересылка сечения массива из 3-й копии во 2-ю.
Если без скобок то обращение к локальному, т.е. в первой копии программы пересылка массива А в k-ю копию A[k] = A равносильно A[k] = A[1]
Для определения номера копии программы по индексам coarray используется функция image_index().
program CAF
complex Y(50)[1,1:*]
if (this_image() == 1) then ! == 2
write(*,*) "This is ", this_image(),
" copy of program "
write(*,*) "Image index = ",
image_index(Y, [1,this_image()])
write(*,*) "Coordinates = ", this_image(Y)
write(*,*)
end if
This is 1 copy of program
Image index = 1
Coordinates = 1 1
Функция lcobound возвращает нижнюю границу coarray - переменной. Функция ucobound возвращает верхнюю границу coarray - переменной.
type point
integer x
integer y
end type point
type (point) PS(10)[1,-2:*]
! num_images() = 4 ! 1 -2
write(*,*) "LCOBOUND = ", LCOBOUND (PS)
write(*,*) "UCOBOUND = ", UCOBOUND (PS)
! 1 1
Всем images установить значения переменных.
Две копии программы рисующие разные случайные геометрические фигуры. Первая – прямоугольники, Вторая – окружности.
Вариант программы
program prog2
use ifqwin
integer, parameter :: dx = 10, dy = 10
do
call random_number(x); call random_number(y)
call random_number(r); call random_number(g)
call random_number(b)
ires2 = setcolorrgb(rgbtointeger(int(r*255),
int(g*255),
int(b*255)))
if (this_image() == 1) ires2 = rectangle(3,int2(x*800),
int2(y*600),int2(x*800)+dx, int2(y*600)+dy)
if (this_image() == 2) ires2 = ellipse(3,int2(x*800),
int2(y*600),int2(x*800)+dx, int2(y*600)+dy)
end do
end
Барьерная синхронизация. Копии программы приостанавливаются на барьере до тех пор, пока на барьере не окажутся все копии программы.
program CAF
integer, parameter :: M = 100
real A(M,M)[*]
if (this_image() == 1) then
call random_number(A)
A = real(int(A*10))
do k = 2,num_images() ! каждый узнал об изменении
A[k] = A
end do
end if
sync all
...
integer :: i, k1, k2
integer(8) sum = 0, k[*] ! k - coarray-переменная
if (this_image() == 1) then ! --- план для вычислений
k1 = 1; k2 = 100
end if
if (this_image() == 2) then
k1 = 101; k2 = 100000
end if
do i = k1,k2 ! --- расчет каждой копией программы
k[this_image()] = k[this_image()] + i
end do
SYNC ALL ! дожидаемся всех, сколько каждая копия насчитала
if (this_image() == 1) then ! --- сбор результатов
do i = 1,num_images()
sum = sum + k[i]
end do
write(*,*) sum ! 5000050000
end if
end
SYNC IMAGES(image_set)
Синхронизация избранных копий программы,
image_set |
– массив номеров копий программы или просто номер копии |
image_set(*) |
- означает все копии |
if (this_image() == 5) then
! image 5 ожидает других images,
! чтобы завершить использование данных.
sync images(*)
else
sync images(5)
! Другие images ожидают image 5,
! чтобы установить данные,
! но не ожидают никакого другого image.
end if
critical
! операторы, выполняемые в любой момент
! времени только одной копией программы
end critical
program CAF
implicit none
complex Y(50)[1,1:*]
write(*,*) "This is ", this_image(), " copy of program "
write(*,*) "Image index = ", image_index(Y,[1,this_image()])
write(*,*) "Coordinates = ", this_image(Y)
write(*,*)
end program CAF
This is 1 copy of program
This is 2 copy of program
Index = 2
Coordinates = 1 2
Index = 1
Coordinates = 1 1
This is 2 copy of program
This is 1 copy of program
Index = 2
Coordinates = 1 2
Index = 1
Coordinates = 1 1
This is 2 copy of program
This is 1 copy of program
Index = 1
Coordinates = 1 1
Index = 2
Coordinates = 1 2
Экран – критическая секция.
program CAF
implicit none
complex Y(50)[1,1:*]
critical
write(*,*) "This is ", this_image(), " copy of program "
write(*,*) "Image index = ", image_index(Y,[1,this_image()])
write(*,*) "Coordinates = ", this_image(Y)
write(*,*)
end critical
end program CAF
This is 1 copy of program
Image index = 1
Coordinates = 1 1
This is 2 copy of program
Image index = 2
Coordinates = 1 2
Написать программу нахождения максимума в одномерном массиве.
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.