Высокопроизводительные вычисления в России
В последнее время и в России происходит бурный рост интереса к высокопроизводительным вычислениям. Связан он, в первую очередь, с кластерными технологиями, позволяющими получать потенциально очень большую производительность за относительно невысокую стоимость. Кластерные установки появляются повсеместно, их число и мощность растет очень быстро.
Так, например, кластером является и самый мощный российский суперкомпьютер МВС-1000М, установленный в Межведомственном суперкомпьютерном центре в Москве (http://www.jscc.ru/). Компьютер состоит из шести базовых блоков, содержащих по 64 двухпроцессорных модуля. Каждый модуль имеет два процессора Alpha 21264/667 МГц (кэш-память второго уровня 4 Мбайта), 2 Гбайта оперативной памяти, разделяемой процессорами модуля, жесткий диск. Общее число процессоров в системе равно 768, а пиковая производительность МВС-1000М превышает 1 TFLOPS. В 20-ой редакции списка 500 наиболее мощных компьютеров мира Top500 компьютер МВС-1000М занимает 74-е место.
Модель программирования.
MIMD и SPMD
На мультикомпьютерах реализуется MIMD (Multiple Instructions Multiple Data) модель параллелизма. Это значит, что параллельная программа представлена множеством процессов, обрабатывающих различные данные. Процессы, вообще говоря, могут быть порождены запуском различных исполняемых файлов. Более удобной в программировании является модель SPMD (Single Program Multiple Data) — запускается несколько одинаковых процессов с различными данными. Эта модель называется «параллелизм по данным». MPI поддерживает обе эти модели, но использоваться будет модель SMPD, так как она существенно упрощает работу с системой очередей и в ней легче программировать.
Коммуникаторы
Процессы объединены в коммуникаторы. Все передачи сообщений происходят в пределах какого-то конкретного коммуникатора. В программе по умолчанию создается коммуникатор, который объединяет все процессы программы - MPI_COMM_WORLD.
Функция MPI_Init(int *argc, char *** argv)производит инициализацию MPI. Должна быть первой из вызываемых MPI функций. В нее передаются адреса аргументов функции main().
Командой mpiexec (mpirun) один и тот же исполняемый файл (точнее, файлы с одним и тем же именем в рабочей директории на разных узлах) запускаются на исполнение. Поскольку SPMD распараллеливание предполагает разделение работы между одновременно работающими устройствами, эти устройства должны выполнять различные части программы. Нет никакого смысла в том, что все устройства выполнят абсолютно одни и те же действия. Когда исполняемый файл запускается, соответствующий процесс должен получить какой-то отличительный признак, по которому этот процесс будет идентифицироваться. Таким признаком является ранг(номер) процесса. Ранг служит двум целям: процесс определяет свою часть работы, зная свой ранг, и при обмене сообщениями между двумя процессами, эти процессам необходимо знать ранги друг друга.
Кроме того, почти всегда необходимо знать общее число процессов программы. Для этого используется следующая пара функций:
MPI_Comm_rank(MPI_Comm comm, int* rank)
записывает по адресу rank ранг вызвавшего процесса в коммуникаторе comm В разных коммуникаторах один и тот же процесс может иметь различные ранги.
MPI_Comm_size(MPI_Comm comm, int* size)
записывает по адресу size общее число процессов в коммуникаторе comm.
MPI_Finalize()
Производит корректное завершение среды MPI. После вызова этой функции нельзя вызывать другие функции MPI. Эта функция обязательно должна вызываться до завершения программы.
Компиляция и запуск параллельных программ
Компиляция
Fortran — mpif77
C — mpicc
C++ —mpicxx (mpiCC в MPICH1.*)
Запуск
MPICH 2.*
mpiexec -n [-gdb ]<число процессов> <имя исполняемого файла> <список параметров>
MPICH 1.*
mpirun -np <число процессов> <имя исполняемого файла> <список параметров>
На ЭВМ с системой очередей Sun Grid Engine необходимо писать специальный сценарий и ставить в очередь не команду mpirun, а этот сценарий.
Пример сценария
#!/bin/bash
#$ -cwd
#$ -V
mpirun -np $NSLOTS -machinefile $TMPDIR/machines ./a.out
Управление очередями
qsub -pe mpich < число процессоров > < Имя сценария >
Постановка задачи в очередь
qstat [-f]
Просмотр состояния очереди
qdel [-f] <номер задачи>
Удаление задачи из очереди
На ЭВМ семейства MVS команда mpirun представляет собой обертку для постановки задачи в очередь.
Первая программа "Hello, MPI world!"
Hello.c
#include<mpi.h>
#include<stdio.h>
int main(int argc, char** argv)
{
int rank, size;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
MPI_Comm_size(MPI_COMM_WORLD,&size);
printf("Hello, MPI world! I am %d of %d\n",rank,size);
MPI_Finalize();
return 0;
}
Mpicc hello.c -o hello
Mpiexec -n 10 ./hello
Hello, MPI world! I am 0 of 10
Hello, MPI world! I am 2 of 10
Hello, MPI world! I am 3 of 10
Hello, MPI world! I am 1 of 10
Hello, MPI world! I am 9 of 10
Hello, MPI world! I am 5 of 10
Hello, MPI world! I am 4 of 10
Hello, MPI world! I am 6 of 10
Hello, MPI world! I am 8 of 10
Hello, MPI world! I am 7 of 10
Порядок строчек, вообще говоря, неопределен. Из-за того, что экран является разделяемым ресурсом, доступ к которому не контролируется, возможна ситуация, когда весь вывод "перемешается". Чтобы этого не произошло, заголовок mpi.h всегда должен подключаться первым.