Этот пример иллюстрирует как перекрывать расчеты и вывод. Расчеты производятся
функцией compute_buffer().
/*===============================================================
*
* Функция: double_buffer
*
* Определение:
* void double_buffer(
* MPI_File fh, ** IN
* MPI_Datatype buftype, ** IN
* int bufcount ** IN
* )
*
* Описание:
* Перекрывает расчеты и коллективную запись используя
* технику двойной буферизации.
*
* Параметры:
* fh дескриптор открытого файла MPI
* buftype тип данных MPI для размещения в памяти
* (Предполагает, что для fh установлен
* совместимое отображение)
* bufcount # элементы типа buftype для передачи
*-------------------------------------------------------------*/
/* это макро переключает используемый буфер "x" */
#define TOGGLE_PTR(x) (((x)==(buffer1))?(x=buffer2):(x=buffer1))
void double_buffer( MPI_File fh, MPI_Datatype buftype,
int bufcount)
{
MPI_Status status; /* статус вызова MPI */
float *buffer1, *buffer2; /* буфер для результатов */
float *compute_buf_ptr; /* буфер назначения */
/* для расчетов */
float *write_buf_ptr; /* источник для записи */
int done; /* определяет, когда выходить*/
/* инициализация буфера */
buffer1 = (float *)
malloc(bufcount*sizeof(float)) ;
buffer2 = (float *)
malloc(bufcount*sizeof(float)) ;
compute_buf_ptr = buffer1 ;
/* изначально указывает на buffer1 */
write_buf_ptr = buffer1 ;
/* изначально указывает на buffer1 */
/* пролог DOUBLE-BUFFER:
* рассчитать buffer1; затем начать запись на диск buffer1
*/
compute_buffer(compute_buf_ptr, bufcount, &done);
MPI_File_write_all_begin(fh, write_buf_ptr,
bufcount, buftype);
/* устойчивое состояние DOUBLE-BUFFER:
* перекрываем запись старых результатов из буфера, на
* который указывает write_buf_ptr
* расчетами новых результатов в буфер, на который указывает
* compute_buf_ptr.
*
* В устойчивом состоянии всегда исполузуется один буфер для
* расчетов и один для записи.
*/
while (!done) {
TOGGLE_PTR(compute_buf_ptr);
compute_buffer(compute_buf_ptr, bufcount, &done);
MPI_File_write_all_end(fh, write_buf_ptr, &status);
TOGGLE_PTR(write_buf_ptr);
MPI_File_write_all_begin(fh, write_buf_ptr,
bufcount, buftype);
}
/* эпилог DOUBLE-BUFFER:
* ждем завершения последней записи.
*/
MPI_File_write_all_end(fh, write_buf_ptr, &status);
/* очищаем буферы */
free(buffer1);
free(buffer2);
}