По умолчанию профилирование создает набор статистических данных для всего кода между вызовами процедур PetscInitialize () и PetscFinalize () в программе. Существует возможность создания независимого мониторинга до десяти секций кода, переключение между мониторингом которых производится функциями:
PetscLogStagePop ();
PetscLogStageRegister (int stage,char *name)
позволяет ассоциировать имя с этапом; эти имена выводятся при генерации итогов через -log_summary или PetscLogPrintSummary (). Следующий фрагмент кода использует три этапа профилирования:
/* этап 0 кода здесь */
PetscLogStageRegister (0,"Этап 0 кода");
for (i=0; i<ntimes; i++) {
PetscLogStagePush(1);
PetscLogStageRegister(1,"Этап 1 кода");
/* этап 1 кода здесь */
PetscLogStagePop();
PetscLogStagePush(2);
PetscLogStageRegister(1,"Этап 2 кода");
/* этап 2 кода здесь */
PetscLogStagePop();
}
PetscFinalize ();
Приведенные выше примеры показывают вывод, сгенерированный опцией -log_summary, для программы, использующей несколько этапов профилирования. В частности, эта программа подразделяется на шесть частей: загрузка матрицы и вектора правой стороны из двоичного файла, настройка предобработчика, решение линейной системы; эта последовательность затем повторяется для второй линейной системы. Для простоты во втором примере дан вывод только для этапов 4 и 5 (линейное решение второй системы), которые содержат часть наиболее интересных для нас вычислений с точки зрения мониторинга производительности. Такая организация кода (решение небольшой линейной системы, а затем решение большой) позволяет сгенерировать более точную статистику профилирования для второй системы, избегая часто встречающейся постраничной перегрузки.