| |
Примеры в этом разделе иллюстрируют приложения гарантий непротиворечивости и семантики MPI. Они показывают
/* Process 0*/Пользователь может гарантировать, что запись в процессе 0 предшествует чтению в процессе 1, вводя временной порядок, например, вызовами MPI_BARRIER(комментированными в приведенном выше коде).
int i, a[10];
int TRUE = 1;
for(i=0;i<10;i++)
a[i] = 5;
_File_open(MPI_COMM_WORLD, ``workfile'',
MPI_MODE_RDWR | MPI_MODE_CREATE,
MPI_INFO_NULL, &fh0 );
_File_set_view( fh0, 0, MPI_INT, MPI_INT, ``native'',
MPI_INFO_NULL );
MPI_File_set_atomicity( fh0, TRUE );
MPI_File_write_at(fh0, 0, a, 10, MPI_INT, &status);
/* MPI_Barrier( MPI_COMM_WORLD ) ;*/
/* Process 1 */
int b[10];
int TRUE = 1;
MPI_File_open(MPI_COMM_WORLD, ``workfile'',
MPI_MODE_RDWR | MPI_MODE_CREATE,
MPI_INFO_NULL, &fh1 );
_File_set_view( fh1, 0, MPI_INT, MPI_INT, ``native'',
MPI_INFO_NULL );
MPI_File_set_atomicity( fh1, TRUE ) ;
/* MPI_Barrier( MPI_COMM_WORLD ) ; */
MPI_File_read_at(fhl, 0, b, 10, MPI_INT, &status);
Совет пользователям: Для установления временного порядка можно использовать процедуры, иные, чем MPI_BARRIER. В примере, приведенном выше, процесс 0 мог бы использовать MPI_SEND для отсылки сообщения длиной 0 байт, которое принимается процессом 1, используя MPI_RECV.[]
С другой стороны, пользователь может ввести непротиворечивость при установленном неатомарном режиме:
/* Process 0 */
int i, a[10];
for (i=0;i<10;i++)
a[i] = 5;
_File_open(MPI_COMM_WORLD,``workfile'',
MPI_MODE_RDWR | MPI_MODE_CREATE,
MPI_INFO_NULL, &fh0 );
_File_set_view(fh0, 0, MPI_INT, MPI_INT,
SPMgt;``native'', MPI_INFO_NULL);
MPI_File_write_at(fh0, 0, a, 10, MPI_INT, &status) ;
MPI_File_sync( fh0 ) ;
MPI_Barrier( MPI_COMM_WORLD ) ;
MPI_File_sync( fh0 ) ;
/* Process 1 */
int b[10] ;
MPI_File_open( MPI_COMM_WORLD, ``workfile'',
MPI_MODE_RDWR | MPI_MODE_CREATE,
MPI_INFO_NULL, &fh1 ) ;
_File_set_view( fh1, 0, MPI_INT, MPI_INT,
SPMgt;``native'', MPI_INFO_NULL ) ;
MPI_File_sync( fh1 ) ;
MPI_Barrier( MPI_COMM_WORLD) ;
MPI_File_sync( fh1 ) ;
MPI_File_read_at(fh1, 0, b, 10, MPI_INT, &status);
Конструкция ``sync-barrier-sync'' требуется, поскольку:
Следующая программа представляет ошибочный способ достижения непротиворечивости при удалении кажущегося лишним второго вызова ``sync'' в каждом процессе.
/* - - - - - - - - - - ЭТОТ ПРИМЕР СОДЕРЖИТ ОШИБКУ - - - - - - - - - - */
/* Process 0 */
int i, a[10];
for(i=0;i<10;i++)
a[i] = 5;
_File_open( MPI_COMM_WORLD, ``workfile'',
MPI_MODE_RDWR | MPI_MODE_CREATE,
MPI_INFO_NULL, &fh0 );
_File_set_view( fh0, 0, MPI_INT, MPI_INT,
SPMgt;``native'', MPI_INFO_NULL);
MPI_File_write_at(fh0, 0, a, 10, MPI_INT, &status) ;
MPI_File_sync( fh0 ) ;
MPI_Barrier( MPI_COMM_WORLD ) ;
/* Process 1 */
int b[10] ;
_File_open( MPI_COMM_WORLD, ``workfile'',
MPI_MODE_RDWR | MPI_MODE_CREATE,
MPI_INFO_NULL, &fh1 ) ;
_File_set_view( fh1, 0, MPI_INT, MPI_INT,
SPMgt;``native'', MPI_INFO_NULL ) ;
MPI_Barrier( MPI_COMM_WORLD ) ;
MPI_File_sync( fh1 ) ;
MPI_File_read_at(fh1, 0, b, 10, MPI_INT,&status);
/* - - - - - - - - - - ЭТОТ ПРИМЕР СОДЕРЖИТ ОШИБКУ - - - - - - - - - - - */
Приведенная выше программа также нарушает правило MPI, запрещающее неупорядоченные коллективные операции и блокируется в реализациях, у которых MPI_FILE_SYNC блокирующая.
Совет пользователям: Некоторые реализации могут выбрать способ
выполнения
MPI_FILE_SYNC как временно синхронизирующей функции. В этом
случае, приведенная выше конструкция ``sync-barrier-sync'' может быть
заменена одним ``sync''. Однако, такой код не будет перено-
симым.[]
Асинхронный
ввод-вывод. Поведение операций асинхронного ввода-вывода определяется
применением правил, определенных выше для синхронных операций ввода-вывода.
В следующих примерах производится доступ к уже существующему файлу ``myfile''. Слово 10 в ``myfile'' первоначально содержит целое значение 2. Каждый пример записывает, а затем читает слово 10.
Вначале рассмотрим следующий фрагмент кода:
int a = 4, b, TRUE=1;
MPI_File_open( MPI_COMM_WORLD, ``myfile'',
MPI_MODE_RDWR, MPI_INFO_NULL, &fh ) ;
_File_set_view( fh, 0,MPI_INT, MPI_INT, ``native'',
MPI_INFO_NULL );
/* MPI_File_set_atomicity( fh, TRUE ) ;
Используйте это для установки атомарного режима.*/
MPI_File_iwrite_at(fh, 10, &a, 1, MPI_INT, &reqs[0]) ;
MPI_File_iread_at(fh, 10, &b, 1, MPI_INT, &reqs[l]) ;
MPI_Waitall(2, reqs, statuses) ;
Для операций асинхронного доступа к данным MPI определяет, что доступ происходит в любое время между вызовом процедуры асинхронного доступа к данным и завершением соответсвующей процедуры, выполняющей запрос. Поэтому выполнение чтения перед записью или записи перед чтением является непротиворечивым с порядком программы. Если установлен атомарный режим, MPI гарантирует последовательную непротиворечивость, и программа будет считывать из b либо 2, либо 4. Если атомарный режим не установлен, то последовательная непротиворечивость не гарантируется, и программа может иногда считывать что-либо иное, нежели 2 или 4 из-за конфликтов при доступе к данным.
Подобным образом, следующий фрагмент кода не упорядочивает доступ к файлу:
int a = 4, b, TRUE=1;
MPI_File_open( MPI_COMM_WORLD, ``myfile'',
MPI_MODE_RDWR, MPI_INFO_NULL, &fh ) ;
_File_set_view( fh, 0, MPI_INT, MPI_INT, ``native'',
MPI_INFO_NULL );
/* MPI_File_set_atomicity( fh, TRUE ) ;
Используйте это для установки атомарного режима.*/
MPI_File_iwrite_at(fh, 10, &a, 1, MPI_INT, &reqs[0]) ;
MPI_File_iread_at(fh, 10, &b, 1, MPI_INT, &reqs[l]) ;
MPI_Wait(&reqs[0], &status) ;
MPI_Wait(&reqs[l], &status) ;
Если установлен атомарный режим, либо 2, либо 4 будет считываться из b. И вновь, MPI не гарантирует последовательную непротиворечивость в неатомарном режиме.
С другой стороны, следующий фрагмент кода:
int a = 4;
int b;
MPI_File_open(MPI_COMM_WORLD, ``myfile'',
MPI_MODE_RDWR, MPI_INFO_NULL, &fh ) ;
_File_set_view( fh, 0, MPI_INT, MPI_INT, ``native'',
MPI_INFO_NULL );
/* MPI_File_set_atomicity( fh, TRUE ) ;
Используйте это для установки атомарного режима.*/
MPI_File_iwrite_at(fh, 10, &a, 1, MPI_INT, &reqs[0]) ;
MPI_Wait(&reqs[0], &status) ;
MPI_File_iread_at(fh, 10, &b, 1, MPI_INT, &reqs[l]) ;
MPI_Wait(&reqs[l], &status) ;
определяет тот же порядок, что и:
int a = 4, b;
MPI_File_open( MPI_COMM_WORLD, ``myfile'',
MPI_MODE_RDWR, MPI_INFO_NULL, &fh ) ;
_File_set_view( fh, 0, MPI_INT, MPI_INT, ``native'',
MPI_INFO_NULL );
/* MPI_File_set_atomicity( fh, TRUE ) ;
Используйте это для установки атомарного режима.*/
MPI_File_write_at(fh, 10, &a, 1, MPI_INT, &reqs[0]) ;
MPI_File_read_at(fh, 10, &b, 1, MPI_INT, &reqs[l]) ;
Поскольку
MPI гарантирует, что оба фрагмента программы будут считывать из b значение 4. В этом примере не нужно устанавливать атомарный режим.
Такие же рассуждения применяются к конфликтующим потыткам доступа в форме:
MPI_File_write_all_begin(fh,...) ;
MPI_File_iread(fh,...) ;
MPI_Wait(fh,...) ;
MPI_File_write_all_end(fh,...) ;
Помните, что ограничения, управляющие непротиворечивостью и семантикой, не относятся к следующему:
MPI_File_write_all_begin(fh,...) ;
MPI_File_read_all_begin(fh,...) ;
MPI_File_read_all_end(fh,...) ;
MPI_File_write_all_end(fh,...) ;
поскольку раздельные коллективные операции над одним и тем же дескриптором файла могут не перекрываться (см. раздел 7.4.5).
Закладки на сайте Проследить за страницей |
Created 1996-2024 by Maxim Chirkov Добавить, Поддержать, Вебмастеру |