Чтение онлайн

ЖАНРЫ

Программирование для Linux. Профессиональный подход

Самьюэл Алекс

Шрифт:

А.3.3. Отображение профильных данных

Получив имя исполняемого файла, утилита

gprof
проверяет файл
gmon.out
и отображает информацию о том, сколько времени заняло выполнение каждой функции. Давайте проанализируем ход выполнения операции 1787 × 13 - 1918 в нашей программе-калькуляторе, создав простой профиль.

Flat profile:

Each sample counts as 0.01 seconds.

% cumulative self self total

time seconds seconds calls ms/call ms/call name

26.07 1.76 1.76 20795463 0.00 0.00 decrement_number

24.44 3.41 1.65 1787 0.92 1.72 add

19.85 4.75 1.34 62413059 0.00 0.00 zerop

15.11 5.77 1.02 1792 0.57 2.05 destroy_number

14.37 6.74 0.97 20795463 0.00 0.00 add_one

 0.15 6.75 0.01 1788 0.01 0.01 copy_number

 0.00 6.75 0.00 1792 0.00 0.00 make_zero

 0.00 6.75 0.00 11 0.00 0.00 empty_stack

Вычисление

функции
decrement_number
и всех вызываемых в ней функций заняло 26,07% общего времени выполнения программы. Эта функция вызывалась 20795463 раза. Каждый вызов выполнялся 0,00 с, т.е. столь малое время, что его не удалось замерить. Функция
add
вызывалась 1787 раз, очевидно для вычисления произведения. Каждый проход по функции занимал 0,92 секунды. Функция
copy_number
вызывалась почти столько же раз — 1788, но на ее выполнение ушло всего 0.15% общего времени работы программы. Иногда в отчете присутствуют функции
mcount
и
profil
, используемые профайлером.

В простом профиле отражается время, затраченное на выполнение каждой функции. Утилита

gprof
умеет также создавать схему вызовов, где показывается время, проведенное не только в каждой функции, но и во всех вызываемых в ее контексте дочерних функциях.

index % time self children called name

<spontaneous>

[1] 100.0 0.00 6.75 main [1]

0.00 6.75 2/2 apply_binary_function [2]

0.00 0.00 1/1792 destroy_number [4]

0.00 0.00 1/1 number_to_unsigned_int [10]

0.00 0.00 3/3 string_to_number [12]

0.00 0.00 3/5 push_stack [16]

0.00 0.00 1/1 create_stack [16]

0.00 0.00 1/11 empty_stack [14]

0.00 0.00 1/5 pop_stack [15]

0.00 0.00 1/1 clear_stack [17]

– -------------------------------------

0.00 6.75 2/2 main [1]

[2] 100.0 0.00 6.75 2 apply_binary_function [2]

0.00 6.74 1/1 product [3)

0.00 0.01 4/1792 destroy_number [4]

0.00 0.00 1/1 subtract [11]

0.00 0.00 4/11 empty_stack [14]

0.00 0.00 4/5 pop_stack [15]

0.00 0.00 2/5 push_stack [16]

– -------------------------------------

0.00 6.74 1/1 apply_binary_function [2]

[3] 99.6 0.00 6.74 1 product [3]

1.02 2.65 1767/1792 destroy_number [4]

1.65 1.43 1767/1767 add [5]

0.00 0.00 1760/62413059 zerop [7]

0.00 0.00 1/1792 make_zero [13]

В

первой секции сообщается о том, что на выполнение функции
main
и всех ее дочерних функций ушло 100% времени (6.75 секунд). Функцию
main
вызвал некто
<spontaneous>
: это означает, что профайлер не смог определить, как был осуществлен вызов. В функции
main
дважды вызывалась функция
apply_binary_function
(всего таких вызовов в программе было тоже два). В третьей секции сообщается о том, что выполнение функции
product
и ее дочерних функций заняло 98% времени. Эта функция вызывалась только один раз из функции
apply_binary_function
.

По схеме вызовов несложно определить время работы той или иной функции. Однако рекурсивные функции требуют особого подхода. Например, функция

even
вызывает функцию
odd
, а та — снова функцию
even
. Самому длинному из таких циклов присваивается номер и выделяется отдельная секция отчета. Следующий фрагмент профильных данных получен в результате проверки того, является ли результат операции 1787 × 13 × 3 четным:

– -------------------------------------

0.00 0.02 1/1 main [1]

[9] 0.1 0.00 0.02 1 apply_unary_function [9]

0.01 0.00 1/1 even <cycle 1> [13]

0.00 0.00 1/1806 destroy_number [5]

0.00 0.00 1/13 empty_stack [17]

0.00 0.00 1/6 pop_stack [16]

0.00 0.00 1/6 push_stack [19]

– -------------------------------------

[10] 0.1 0.01 0.00 1+69993 <cycle 1 as a whole> [10]

0.00 0.00 34647 even <cycle 1> [13]

– -------------------------------------

34847 even <cycle 1> [13]

[11] 0.1 0.01 0.00 34847 odd <cycle 1> [11]

0.00 0.00 34847/186997954 zerop [7]

Поделиться с друзьями: