Message Passing InterfaceMPI (англ. Message Passing Interface, Інтерфейс передачі повідомлень) — це специфікація, що була розроблена в 1993–1994 роках групою MPI Forum[1],і забезпечує реалізацію моделі обміну повідомленнями між процесами. Остання версія цієї специфікації: MPI-2. У моделі програмування MPI програма породжує кілька процесів, що взаємодіють між собою за допомогою виклику підпрограм прийому й передачі повідомлень. Зазвичай, при ініціалізації MPI-програми створюється фіксований набір процесів, причому (що, утім, необов'язково) кожний з них виконується на своєму процесорі. У цих процесах можуть виконуватися різні програми, тому MPI-модель іноді називають MIMD-моделлю (Multiple Instruction, Multiple Data), на відміну від SIMD моделі, де на кожному процесорі виконуються тільки однакові задачі. MPI підтримує двохточкові й глобальні, синхронні й асинхронні, блокуючі й неблокуючі типи комунікацій. Спеціальний механізм — комунікатор — ховає від програміста внутрішні комунікаційні структури. Структура комунікацій може змінюватися протягом часу життя процесу, але кількість задач має залишатися постійною (MPI-2 підтримує динамічну зміну кількості задач). Специфікація MPI забезпечує переносимість програм на рівні вихідних кодів. Підтримується робота на гетерогенних кластерах і симетричних мультипроцесорних системах. Не підтримується запуск процесів під час виконання MPI-програми. У специфікації відсутні опис паралельного вводу-виводу й налагодження програм — ці можливості можуть бути включені до складу конкретної реалізації MPI у вигляді додаткових пакетів чи утиліт. Сумісність різних реалізацій не гарантується. Важливою властивістю паралельної програми є детермінізм — програма має завжди давати однаковий результат для однакових наборів вхідних даних. Модель передачі повідомлень загалом такої властивості не має, оскільки не визначено порядок одержання повідомлень від двох процесів третім. Якщо ж один процес послідовно надсилає кілька повідомлень іншому процесу, MPI гарантує, що одержувач отримає їх саме в тому порядку, у якому вони були надіслані. Відповідальність за забезпечення детермінованого виконання програми покладається на програміста. MPI-програма#include <mpi.h> // очевидно;)
#include <stdio.h>
int main(int argc, char* argv[])
{
int myrank, size;
MPI_Init(&argc, &argv); // Ініціалізація MPI
MPI_Comm_size(MPI_COMM_WORLD, &size); // Розмір комунікатора
MPI_Comm_rank(MPI_COMM_WORLD, &myrank); // Одержуємо наш номер
printf("Proc %d of %d\n", myrank, size);
MPI_Finalize(); // Фіналізація MPI
puts("Done.");
return 0;
}
Перед викликом будь-якої процедури MPI, потрібно викликати ініціалізацію Proc 1 of 3 Done. Proc 0 of 3 Done. Proc 2 of 3 Done. Зверніть увагу, що після виклику Термінологія і позначення
Процеси об'єднуються в групи, можуть бути вкладені групи. Усередині групи всі процеси перенумеровані. З кожною групою асоційований свій комунікатор. Тому при здійсненні пересилання необхідно вказати ідентифікатор групи, всередині якої проводиться ця пересилка. Всі процеси містяться в групі з наперед визначеним ідентифікатором MPI_COMM_WORLD . Стандарти MPIПерша версія MPI розроблялася в 1993–1994 році, і MPI 1 вийшла в 1994. Більшість сучасних реалізацій MPI підтримують версію 1.1. Стандарт MPI версії 2.0 підтримується більшістю сучасних реалізацій, але деякі функції можуть бути реалізовані не до кінця. У MPI 1.1 (опублікований 12 червня 1995 , перша реалізація з'явилася в 2002 році) підтримуються наступні функції:
У MPI 2.0 (опублікований 18 липня 1997) додатково підтримуються наступні функції:
Версія MPI 2.1 вийшла на початку вересня 2008 року. Версія MPI 2.2 вийшла 4 вересня 2009. Версія MPI 3.0 вийшла 21 вересня 2012 року. Функціонування інтерфейсуБазовим механізмом зв'язку між MPI процесами є передача і прийом повідомлень. Повідомлення несе в собі передані дані і інформацію, що дозволяє приймаючій стороні здійснювати їх вибірковий прийом:
Операції прийому й передачі можуть бути блокуючі і неблокуючі. Для неблокуючих операцій визначені функції перевірки готовності й очікування виконання операції. Іншим способом зв'язку є віддалений доступ до пам'яті (RMA), що дозволяє читати і змінювати область пам'яті віддаленого процесу. Локальний процес може переносити область пам'яті віддаленого процесу (всередині зазначеного процесами вікна) в свою пам'ять і назад, а також комбінувати дані, передані у віддалений процес, з наявними в його пам'яті даними (наприклад, шляхом підсумовування). Всі операції віддаленого доступу до пам'яті не блокуються, однак, до і після їх виконання необхідно викликати блокуючі функції синхронізації. Реалізації MPI
Загальні процедури MPIint MPI_Init (INT * ARGC, char *** ARGV) MPI_Init — ініціалізація паралельної частини програми. Реальна ініціалізація для кожного додатка виконується не більше одного разу, а якщо MPI вже був ініціалізований, то ніякі дії не виконуються і відбувається негайне повернення з підпрограми. Всі інші MPI-процедури можуть бути викликані тільки після виклику MPI_Init . Повертає: у разі успішного виконання — MPI_SUCCESS, інакше — код помилки. (Те ж саме повертають і всі інші функції MPI_*, вказані нижче) int MPI_Finalize (void) MPI_Finalize — завершення паралельної частини програми. Всі наступні звернення до будь-яких MPI-процедур (зокрема — до MPI_Init) заборонено. До моменту виклику якимось процесом MPI_Finalize має бути завершено всі дії, що вимагають його участі в обміні повідомленнями. int MPI_Comm_size(MPI_Comm comm, int* size) Показує розмір (кількість паралельних процесів) групи, асоційованої з комунікатором
Прийом / передача повідомлень між окремими процесамиПрийом / передача повідомлень з блокуваннямint MPI_Send(void* buf, int count, MPI_Datatype datatype, int dest, int msgtag, MPI_Comm comm)
Блокуюче надсилання повідомлення з ідентифікатором msgtag, що складається з count елементів типу datatype, процесу з номером dest . Всі елементи повідомлення розташовані поспіль в буфері buf . Значення count може бути нулем. Тип переданих елементів datatype повинен вказуватися за допомогою зумовлених констант типу. Дозволяється передавати повідомлення самому собі. Блокування гарантує коректність повторного використання всіх параметрів після повернення з підпрограми. Вибір способу здійснення цієї гарантії: копіювання в проміжний буфер або безпосередня передача процесу dest, залишається за MPI. Слід спеціально зазначити, що повернення з підпрограми MPI_Send не значить ні того, що повідомлення вже передано процесу dest, ні навіть того, що повідомлення залишило процесор, з якого його було надіслано. Прийом / передача повідомлень без блокуванняint MPI_Isend(void *buf, int count, MPI_Datatype datatype, int dest, int msgtag, MPI_Comm comm, MPI_Request *request) Передача повідомлення, аналогічна MPI_Send, проте повернення з підпрограми відбувається відразу після ініціалізації процесу передачі без очікування обробки всього повідомлення, що у буфері buf . Це означає, що не можна повторно використовувати даний буфер для інших цілей без отримання додаткової інформації про завершення даної посилки. Закінчення процесу передачі (тобто того моменту, коли можна перевикористати буфер buf без побоювання зіпсувати передане повідомлення) можна визначити за допомогою параметра request і процедур MPI_Wait і MPI_Test . Повідомлення, відправлене будь-якою з процедур MPI_Send і MPI_Isend, може бути прийняте будь-якою з процедур MPI_Recv і MPI_Irecv Синхронізація процесівint MPI_Barrier (MPI_Comm comm)
Блокує роботу процесів, що викликали дану процедуру, доки всі інші процеси групи comm також не виконають цю процедуру. Визначені константи
Див. такожПримітки
Посилання
|
Portal di Ensiklopedia Dunia