Рассмотрим классический пример задачи: программу "Hello world". Программа может быть запущена в среде MPI на произвольном количестве процессоров. Каждая копия программы, будучи запущена на своем узле кластера, перчатает приветствие, номер процесса, вызвавшего функцию печати и общее количество процессов.
Текст программы следующий:
program hello include 'mpif.h' integer rank, size, ierr call MPI_INIT(ierr) call MPI_COMM_RANK(MPI_COMM_WORLD,rank,ierr) call MPI_COMM_SIZE(MPI_COMM_WORLD,size,ierr) print *,"Hello world! I am ",rank," of ",size call MPI_FINALIZE(ierr) stop end
Теперь рассмотрим более осмысленную задачу. Возьмем за основу вычисление числа .
Число
будем вычислять как определенный интеграл :
![](/img1/img4.gif)
Согласно правилу прямоугольников интеграл можно заменить суммой:
![](/img1/img5.gif)
Теперь посмотрим как этот алгоритм можно реализовать на языке FORTRAN в многопроцессорном параллельном варианте, с использованием системы MPI: pi-mpi.f
program calc_pi include 'mpif.h' integer i, n double precision w, gsum, sum double precision v integer np, myid, ierr real*8 time, mflops, time1, time2, dsecnd c Инициализация MPI и определение процессорной конфигурации call MPI_INIT( ierr ) call MPI_COMM_RANK( MPI_COMM_WORLD, myid, ierr ) call MPI_COMM_SIZE( MPI_COMM_WORLD, np, ierr ) c Информацию с клавиатуры считывает 0-й процессор if ( myid .eq. 0 ) then n = 400000000 time1 = MPI_Wtime() endif c Рассылка числа точек разбиения всем процессорам call MPI_BCAST(n, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr) c Вычисление частичной суммы на процессоре w = 1.0 / n sum = 0.0d0 c Вычисление процессом своей части суммы do i = myid+1, n, np v = (i - 0.5d0 ) * w v = 4.0d0 / (1.0d0 + v * v) sum = sum + v end do c Суммирование частичных сумм с сохранением результата в 0-м c процессоре call MPI_REDUCE(sum, gsum, 1, MPI_DOUBLE_PRECISION, $ MPI_SUM, 0, MPI_COMM_WORLD, ierr) c Печать выходной информации с 0-го процессора if (myid .eq. 0) then time2 = MPI_Wtime() time = time2 - time1 mflops = 9 * n / (1000000.0 * time) print *, 'pi is approximated with ', gsum *w print *, 'time = ', time, ' seconds' print *, 'mflops = ', mflops, ' on ', np, ' processors' print *, 'mflops = ', mflops/np, ' for one processor' endif c Закрытие MPI call MPI_FINALIZE(ierr) end