next up previous contents
Next: Устаревшие функции Up: Кэширование Previous: Функциональные возможности   Contents

Пример c атрибутами

Совет пользователям: Этот пример показывает, как написать коллективную операцию обмена, которая использует кэширование для повышения эффективности после первого вызова. Стиль кодирования предполагает, что в результатах функции MPI возвращаются только ошибочные статусы.[]

/* ключ для этого модуля: */ static int gop_key = MPI_KEYVAL_INVALID; typedef struct { int ref_count; /* счетчик ссылок */ /* другие обьявления, если они понадобятся */ } gop_stuff_type; Efficient_Collective_Op (comm, ...) MPI_Comm comm; { gop_stuff_type *gop_stuff; MPI_Group group; int foundflag; MPI_Comm_group(comm, &group); if (gop_key == MPI_KEYVAL_INVALID) /* Получение ключа на первом вызове */ { if (! MPI_Keyval_create(gop_stuff_copier, gop_stuff_destructor, &gop_key, (void *)0)); /* Получение ключа при назначении его копии, и исключение действия обратного вызова. */ MPI_Abort (comm, 99); } MPI_Attr_get (comm, gop_key, &gop_stuff, &foundflag); if (foundflag) /* Этот модуль уже выполнился в этой группе. Далее будет использоватся кэшируемая информация */ } else {/* Эта группа еще не была кэширована. Это будет сделано сейчас. */ /* Во-первых, следует выделить память для нужных данных и инициализировать cчетчик ссылки */ gop_stuff = gop_stuff_type *) malloc (sizeof(gop_stuff_type)); if (gop_stuff == NULL) { /* прерывается по ошибке нехватки памяти */} gop_stuff -> ref_count = 1; /* Во вторых, следует заполнить *gop_stuff желаемым значени ем.Эта часть здесь не показана */ /* Третье, следует сохранить gop_stuff как значение атрибута */ MPI_Attr_put (comm, gop_key, gop_stuff); } /* Затем, в любом случае, следует использовать значение *gop_stuff, чтобы выполнить глобальную op ... */ } /* Следующая подпрограмма вызывается MPI, когда группа удаляется */ gop_stuff_destructor (comm, keyval, gop_stuff, extra) MPI_Comm comm; int keyval; gop_stuff_type *gop_stuff; void *extra; { if (keyval != gop_key) { /* Прекращение работы из-за ошибки программы*/ } /* Освобождаемая группа удаляет одну ссылку на gop_stuff */ gop_stuff -> ref_count -= 1; /* Если не осталось ни одной ссылки, то освобождаетcя память*/ if (gop_stuff -> ref_count == 0) { free((void *)gop_stuff); } } /* Следующая подпрограмма вызывается MPI, когда группа скопирована */ gop_stuff_copier (comm, keyval, extra, gop_stuff_in, gop_stuff_out, flag) MPI_Comm comm; int keyval; gop_stuff_type *gop_stuff_in, *gop_stuff_out; void *extra; { if (keyval != gop_key) { /* Прекращение работы из-за ошибки программы*/ } /* Новая группа добавляет одну ссылку к gop_stuff */ gop_stuff -> ref_count += 1; gop_stuff_out = gop_stuff_in; }



Alex Otwagin 2002-12-10