Наши партнеры

UnixForum





Библиотека сайта rus-linux.net

На главную -> MyLDP -> Программирование и алгоритмические языки


Ulrich Drepper "Как писать разделяемые библиотеки"
Назад Оглавление Вперед

1.7. Измерение производительности ld.so

Чтобы выполнять оптимизацию, полезно иметь количественную оценку эффекта оптимизации. К счастью, это очень легко сделать с помощью динамического компоновщика glibc. С помощью переменной среды окружения LD DEBUG можно указать, что нужно выдавать дамп информации, относящейся к производительности при запуске приложения. На рис.8 показан пример обращения к программе echo для этого случая.

Рис.8: Сбор статистики при запуске

Динамический компоновщик выдает данные в два этапа. Та часть, которая будет выдана перед данными, выдаваемыми самой программой, выдается прямо перед тем, как динамический компоновщик передаст управление приложению после выполнения всех работ, которые мы описали в этом разделе. Вторая часть, итоговая, выдается (как правило) после того, как приложение будет завершено. Реальный формат может различаться в зависимости от архитектуры. Информация о времени указывается только для тех архитектур, в которых предоставлен простой доступ к регистру счетчика циклов процессора (в данный момент, это современные архитектуры IA-32, IA-64, x86-64, Alpha ). Для других вариантов архитектуры эти строки просто отсутствуют.

Информация о времени указывает абсолютные значения общего времени, потраченного на запуск приложения с динамическим компоновщиком, времени, необходимого для выполнения перемещений, и времени, потраченного в ядре для загрузки/отображения двоичных модулей. В нашем примере время обработки перемещений превышает затраты на запуск более чем на 50%. Здесь есть большой потенциал для оптимизации. В качестве единицы измерения используется количество циклов процессора. Это значит, что значения несравнимы даже для различных реализаций для одной и той же архитектуры. Например, измерения, выполненные на машинах PentiumRM III и PentiumRM 4, будут абсолютно различными. Но эти измерения идеально подходят для оценки улучшений, выполняемых на одной и той же машине, что нас здесь и интересует.

Поскольку перемещения являются такой важной частью производительности во время запуска программы, выдается информация о количестве перемещений. В примере, где используется динамический компоновщик, библиотека языка С и сам исполняемый модуль, выполняется в общей сложности 133 перемещения. Из них 5 перемещений обслуживают перемещения, связанные с кэш-памятью. Такая оптимизация реализована в динамическом компоновщике с тем, чтобы сделать более эффективной обработку случаев, когда перемещение одного и того же символа выполняется неоднократно. После того, как программа сама завершится, та же самая информация выводится снова. Общее количество перемещений здесь больше, поскольку выполнение кода приложения вызвало ряд перемещений периода выполнения программы, если быть точным, то 55 перемещений.

Количество обрабатываемых перемещений не изменяется при каждом выполнении программы. Значения времени, полученные при измерении, изменяются. Даже в однопользовательском режиме, когда нет других работающих программ, разница может присутствовать из-за доступа к кэш-памяти и к основной памяти. Поэтому необходимо усреднять время выполнения для нескольких запусков программы.

Очевидно, что также можно подсчитать количество перемещений без запуска программы. Выполнение readelf -d с указанием двоичного модуля покажет нам динамическую секцию, в которой нас интересуют записи DT RELSZ, DT RELENT, DT RELCOUNT и DT PLTRELSZ. Они позволяют вычислить количество обычных и относительных перемещений, а также количество записей в таблице PLT. Если нет желания делать это вручную, можно воспользоваться скриптом relinfo, который приведен в приложении A.


Предыдущий раздел:   Следующий раздел:
Назад Оглавление Вперед