next up previous contents
Next: Поддержка языка ФОРТРАН Up: С++ Previous: Работа со смешанными языками.   Contents

Профилирование

Эта глава описывает требования для интерфейса профилирования С++ и MPI.

Совет разработчикам: Так как основная цель профилирования - перехват вызовов функций из кода пользователя, то реализация нижних уровней, позволяющая перехват и профилирование вызовов функций оставляется на усмотрение разработчика. Если реализация привязок С++ к MPI выполнена над привязками другого языка (такого как Си), или если привязки С++ находятся над интерфейсом профилирования другого языка, то дополнительный интерфейс не нужен, так как реализация MPI нижнего уровня уже соответствует требованиям интерфейса профилирования MPI.

Реализации MPI с чистым С++, которые не имеют доступа к другим интерфейсам профилирования, должны реализовать интерфейс, соответствующий требованиям, отмеченным в этой главе.

Высококачественные реализации могут реализовать интерфейс, описанный в этой главе с целью распространения переносимых библиотек профилирования С++. Разработчики могут пожелать предоставить выбор - встраивать интерфейс профилирования для С++ или нет; те реализации С++, которые уже находятся над привязками другого языка или другого интерфейса должны будут вставить третий уровень для реализации интерфейса профилирования С++.[]

Для соответствия рекомендациям для интерфейса профилирования С++ для MPI, реализация функций MPI должна:

  1. Предоставить механизм, через который функции, определенные в MPI могут быть доступны с измененным именем. Таким образом, все классы MPI и статические функции-члены (которые обычно начинаются с префиксом ``MPI::'') должны быть также доступны с префиксом ``PMPI::''.
  2. Убедиться, что те функции MPI, которые не были заменены, могут быть скомпонованы в исполняемый файл без конфликтов имен.
  3. Документировать реализацию различных языковых привязок интерфейса MPI если они находятся на разных уровнях, чтобы разработчики профайлера знали, должны они реализовывать интерфейс профилирования для каждой привязки или могут реализовать его только для процедур самого низкого уровня.
  4. Там, где реализация различных языковых привязок сделана с послойным подходом (например, привязка С++ - набор функций-надстроек, вызывающих реализацию Си), убедиться, что функции-надстройки отделены от остальной библиотеки.

    Это необходимо, чтобы позволить отдельной библиотеке профилирования быть реализованной правильно, так как (по крайней мере, с семантикой компоновщика в UNIX) библиотека профилирования должна содержать эти надстройки для ожидаемой работы. Это требование позволяет автору библиотеки профилирования выделить эти функции из оригинальной библиотеки MPI и добавить их в библиотеку профилирования без добавления бесполезного кода.

  5. Предоставить функцию MPI::Pcontrol без операндов в библиотеке MPI.
Совет разработчикам: Существует (как минимум) два очевидных пути реализации интерфейса профилирования для С++: наследование и вложенность. Подход, основанный на наследовании может быть не очень привлекательным, так как он может потребовать виртуального наследования классов коммуникаторов. Поэтому, скорее всего разработчики будут помещать объекты PMPI внутрь соответствующих объектов MPI. Схема вложения описана далее.

``Настоящие'' точки входа для каждой процедуры могут быть предоставлены в поле имен PMPI (namespace PMPI). Обычная версия тогда может быть предоставлена в поле имен MPI.

Вложение экземпляров объектов PMPI в дескриптор MPI предоставляет отношение ``включает'', что необходимо для схемы профилирования .

Каждый экземпляр объекта MPI просто ``надстраивается'' над экземпляром объекта PMPI. Объекты MPI могут производить операции профилирования до вызова соответствующей функции их внутреннего объекта PMPI. Это справедливо как для базовых классов, так и для порожденных; иерархия PMPI прямо соответствует иерархии MPI.

Ключом к тому, чтобы заставить профилирование заработать при простой перекомпоновке программы, является заголовочный файл, который объявляет все функции MPI. Функции должны быть определены в другом месте и скомпилированы в библиотеку. Константы MPI должны быть объявлены как extern в поле имен MPI. Например, этот фрагмент из демонстрационного файла mpi.h:

Пример 8.6    Демонстрационный файл mpi.h. namespace PMPI { class Comm { public: int Get_size() const; }; // и т.д. }; namespace MPI { public: class Comm { public: int Get_size() const; private: PMPI::Comm pmpi_comm; }; }; Заметьте - все конструкторы, оператор присваивания и деструктор в классе MPI должны будут инициализировать/уничтожить соответствующий внутренний объект PMPI.

Объявления функций должны быть в отдельных объектных файлах; член-функции класса PMPI и версии член-функций класса MPI без профилирования могут быть скомпилированы в libmpi.a, когда версии с профилированием могут быть скомпилированы в libpmpi.a. Заметьте, что член-функции класса PMPI и константы MPI должны быть в отдельных от член-функций класса MPI без профилирования объектных файлах библиотеки libmpi.a, чтобы предотвратить многократное определение имен член-функций класса MPI при одновременной компоновке libmpi.a и libpmpi.a. Например:

Пример 8.7    pmpi.cc будет скомпилирован в libmpi.a. int PMPI::Comm::Get_size() const { // Реализация MPI_COMM_SIZE } Пример 8.8    constants.cc, будет скомпилирован в libmpi.a. const MPI::Intracomm MPI::COMM_WORLD; Пример 8.9    mpi_no_profile.cc, будет скомпилирован в libmpi.a. int MPI::Comm::Get_size() const { return pmpi_comm.Get_size(); } Пример 8.10    mpi_profile.cc, будет скомпилирован в libpmpi.a. int MPI::Comm::Get_size() const { // профилирование int ret = pmpi_comm.Get_size(); // дальнейшее профилирование return ret; }



Alex Otwagin 2002-12-10