next up previous contents
Next: Типы данных С++ Up: С++ Previous: Функции-члены классов для MPI   Contents

Семантика.

Семантика функций-членов, составлявляющих привязку С++ к MPI определяется самим описанием функций MPI. Здесь мы определим семантику тех частей интерфейса языка С++, которые не являются частью языковой привязки. В этой части прототипы функций описаны, используя тип MPI::<CLASS> вместо описания каждой функции для каждого класса MPI; слово <CLASS> может быть заменено любым подходящим именем класса MPI (например, Group), за некоторыми описанными исключениями.

Конструкторы и деструкторы. Конструкторы и деструкторы по умолчанию описаны следующим образом: MPI::<CLASS>() ~MPI::<CLASS>()

В терминах конструкторов и деструкторов, явные объекты MPI уровня пользователя ведут себя как дескрипторы. Конструкторы по умолчанию для всех объектов кроме MPI::Status создают соответствующие дескрипторы MPI::*_NULL. То есть, когда создан экземпляр объекта MPI, сравнение его с соответствующим объектом MPI::*_NULL даст положительный результат. Конструкторы по умолчанию не создают новых явных объектов MPI. Некоторые классы для этого имеют в своем составе функцию Create().

Пример 8.2    В этом фрагменте проверка даст истинный результат и на cout будет выведено сообщение: void foo() { MPI::Intracomm bar; if (bar == MPI::COMM_NULL) cout << "bar is MPI::COMM_NULL" << endl; }

Деструктор для каждого объекта MPI уровня пользователя не вызывает соответствующую функцию MPI_*_FREE (если она существует).

Объяснение: Функции MPI_*_FREE не вызываются автоматически в следующих случаях:

  1. Автоматическое разрушение объекта противоречит семантике копирования по ссылке классов MPI.

  2. Основа модели MPI оставляет выделение и освобождение памяти под ответственность пользователя, а не реализации MPI.
  3. Вызов MPI_*_FREE во время разрушения объекта может вызвать непредусмотренные побочные эффекты, включая переключение совместных операций (это также касается семантики копирования, присваивания и создания объектов). В следующем примере мы хотим, чтобы ни foo_comm ни bar_comm не вызывали MPI_*_FREE автоматически при выходе из функции. (Конструктор копирования и оператор присваивания, использованные в примере, будут описаны далее) void example_function() { MPI::Intracomm foo_comm(MPI::COMM_WORLD), bar_comm; bar_comm = MPI::COMM_WORLD.Dup(); // остальной код функции }
[]

Копирование и присваивание. Конструктор копирования и оператор присваивания описаны следующим образом: MPI::<CLASS>(const MPI::<CLASS>& data) MPI::<CLASS>& MPI::<CLASS>::operator=(const MPI::<CLASS>& data)

В терминах копирования и присваивания явные объекты MPI уровня пользователя работают как дескрипторы. Конструкторы копирования производят основанные на дескрипторах копии. Объекты MPI::Status являются исключением из этого правила. Эти объекты производят полное копирование объекта для присваивания и создания копий.

Совет разработчикам: Каждый объект MPI уровня пользователя считается содержащим по значению или ссылке реализационно-зависимую информацию о состоянии. Присваивание и копирование дескрипторов MPI объектов может просто копировать такую информацию. []

Пример 8.3    Этот пример использует оператор присваивания. Здесь MPI::Intracomm::Dup() не вызывается для foo_comm. Объект foo_comm - просто псевдоним для MPI::COMM_WORLD. Но bar_comm создан вызовом функции MPI::Intracomm::Dup() и поэтому является другим видом коммуникатора, нежели foo_comm (и поэтому отличающимся от MPI::COMM_WORLD). baz_comm становится псевдонимом для bar_comm. Если дескриптор

bar_comm или baz_comm будет освобожден вызовом MPI_COMM_FREE, он будет установлен в MPI::COMM_NULL. Состояние другого дескриптора будет неопределенным - оно будет неверным, хотя и не обязательно установленным в MPI::COMM_NULL. MPI::Intracomm foo_comm, bar_comm, baz_comm; foo_comm = MPI::COMM_WORLD; bar_comm = MPI::COMM_WORLD.Dup(); baz_comm = bar_comm;

Сравнение. Операторы сравнения описаны следующим образом: bool MPI::<CLASS>::operator==(const MPI::<CLASS>& data) const bool MPI::<CLASS>::operator!=(const MPI::<CLASS>& data) const

Функция operator==() возвращает значение true только когда дескрипторы ссылаются на один и тот же внутренний объект MPI, иначе false. Оператор operator!=() возвращает булевское дополнение для оператора operator==(). Тем не менее, так как класс Status не дескриптор для объекта более низкого уровня, то нет смысла сравнивать экземпляры объекта Status. Поэтому, функции operator==() и operator!=() в этом классе не определены.

Константы. Константы это единичные объекты и объявлены они как const. Заметьте - не все глобальные объекты MPI являются константами. Например, MPI::COMM_WORLD и MPI::COMM_SELF - не объявлены как const.



Alex Otwagin 2002-12-10