Callgrind main () включительно стоит намного меньше 100% - PullRequest
4 голосов
/ 16 февраля 2011

Я профилировал несколько очень простых программ на C ++, работающих в Linux.Общая стоимость main () для всех из них далека от 100%, что-то вроде 3,83%.Я правильно использую callgrind?У меня есть вывод callgrind_annotate с --inclusive=yes, вставленный ниже.

Программа называется heap, которая выполняет простую сортировку кучи.Я использовал команду

valgrind --tool=callgrind ./heap

Затем я набрал

callgrind_annotate --inclusive=yes callgrind.out.25434

Вывод:

`--------------------------------------------------------------------------------

Profile data file 'callgrind.out.25434' (creator: callgrind-3.6.0)

`--------------------------------------------------------------------------------

I1 cache:
D1 cache:
LL cache:
Timerange: Basic block 0 - 361578
Trigger: Program termination
Profiled target:  ./heap (PID 25434, part 1)
Events recorded:  Ir
Events shown:     Ir
Event sort order: Ir
Thresholds:       99
Include dirs:
User annotated:
Auto-annotation:  off

`--------------------------------------------------------------------------------

       Ir
`--------------------------------------------------------------------------------

2,552,558  PROGRAM TOTALS

`--------------------------------------------------------------------------------

       Ir  file:function

`--------------------------------------------------------------------------------

2,552,558  ???:0x00000810 [/lib/ld-2.7.so]

2,515,793  ???:0x00000a60 [/lib/ld-2.7.so]

2,515,219  ???:0x00015270 [/lib/ld-2.7.so]

2,514,780  ???:0x000021e0 [/lib/ld-2.7.so]

2,456,164  ???:0x0000b2f0 [/lib/ld-2.7.so]

2,256,719  ???:0x00009e40 [/lib/ld-2.7.so]

1,702,371  ???:0x00009ac0 [/lib/ld-2.7.so]

  657,883  ???:0x000098e0 [/lib/ld-2.7.so]

  367,045  ???:0x00017040 [/lib/ld-2.7.so]

   33,170  ???:0x080483e0 [/home/test/heap]

   33,036  ???:0x0000ce60 [/lib/ld-2.7.so]

   31,347  ???:0x0000e850 [/lib/ld-2.7.so]

   30,706  ???:(below main) [/lib/libc-2.7.so]

   30,071  ???:0x00008570 [/lib/ld-2.7.so]

   27,954  ???:0x0000f500 [/lib/ld-2.7.so]

   27,758  ???:0x0000ca30 [/lib/ld-2.7.so]

   21,366  ???:0x0001767b [/lib/ld-2.7.so]

1 Ответ

4 голосов
/ 04 декабря 2011

main() - не верхняя функция в графе вызовов.В glibc есть функция _start, которая будет вызывать main(), а также она будет принимать возвращаемое значение из main.Также есть (для динамически связанных программ = почти все) интерпретатор ELF, также известный как динамический компоновщик (время выполнения): /lib/ld-linux.so (это имя используется в linux, в других Unixes что-то вроде / lib/ld.so).Линкер загрузит и инициализирует все динамические библиотеки, необходимые приложению;и он вызывается ОС до _start.

Что делается до main?Загрузка библиотек (открыть файл библиотеки, разобрать его заголовок, отобразить его, принять код для нового местоположения в памяти = обработка перемещений) и инициализировать их (это необходимо как динамически, так и статически связанным библиотекам; обратите внимание, что glibc = libc также библиотека),Каждая библиотека может иметь код, который будет запущен сразу после загрузки библиотеки (__attribute__((constructor)) или нетривиальные конструкторы глобальных объектов).Кроме того, glibc может зарегистрировать некоторые функции, которые будут запускаться после main (например, через atexit(); если main возвращает нормально, они будут вызваны _start), и библиотеки могут иметь функции-деструкторы для глобальных объектов.

ваша программа использует потоки, верхняя функция потоков 1 .. n не будет основной (каждый поток может разделять стек; цепочка вызовов функций из main хранится в стеке потока 0).

В вашем примере мы видим /lib/ld-*.so, и это динамический компоновщик.Кажется, ваше приложение слишком короткое, чтобы его правильно профилировать, и оно использует большое количество динамических библиотек.

...