Рассмотрено профилирование двух программ, наиболее интенсивно утилизирующих процессорные ресурсы на моём домашнем компьютере. У других людей область задач может отличаться от моей, причём на столько, что профилировщик использовать либо невозможно, либо нецелесообразно. Например попытки профилировать библиотеку «QT» и «XULRunner» пока что заканчивались провалом.
Цель документа -- собрать воедино разбросанную по кусочкам информацию о профилировании при помощи GCC и получить конкретный результат. Хотя бы минимальный результат, на котором уже можно строить дальнейшие эксперименты... и, в идеале, может быть даже влиять на дальнейшее развитие профилировщика и профилируемость программ.
Исходные файлы
Дополнение среды (environment)
Код: Выделить всё
# cat /home/eronex/profiler
pre_pkg_setup() {
local x
if hasq generate $PROFILER; then
elog "bashrc is adding \"-fprofile-dir=/var/tmp/fprofile_dir_data/$PN -fprofile-generate -fprofile-correction\" to CFLAGS and CXXFLAGS for $PN"
CFLAGS="$CFLAGS -fprofile-dir=/var/tmp/fprofile_dir_data/$PN -fprofile-generate -fprofile-correction"
CXXFLAGS="$CFLAGS"
fi
if hasq use $PROFILER; then
elog "bashrc is adding \"-fprofile-dir=/var/tmp/fprofile_dir_data/$PN -fprofile-use -fprofile-correction -Wcoverage-mismatch\" to CFLAGS and CXXFLAGS for $PN"
CFLAGS="$CFLAGS -fprofile-dir=/var/tmp/fprofile_dir_data/$PN -fprofile-use -fprofile-correction -Wcoverage-mismatch"
CXXFLAGS="$CFLAGS"
fi
}Разрешение на профилирование
Необходимо создать символические ссылки с именами профилируемых программ на файл «profiler». Например для p7zip, flac и libogg пути будут выглядеть следующим образом:
Код: Выделить всё
# find -L /etc/portage/env/ -type f
/etc/portage/env/app-arch/p7zip
/etc/portage/env/media-libs/libogg
/etc/portage/env/media-libs/flacМесто скопления статистики
Вот здесь: «/var/tmp/fprofile_dir_data/». Необходимо создать каталог и дать ему «полные» права:
Код: Выделить всё
# chmod -v ugo+rwx /var/tmp/fprofile_dir_data/
права доступа «/var/tmp/fprofile_dir_data/» оставлены как 0777 (rwxrwxrwx)Код: Выделить всё
# cat /var/tmp/fprofile_dir_data/rights.sh
#!/bin/bash
chown -Rv eronex:users /var/tmp/fprofile_dir_data/Способ применения
Профилирование «flac»
Сначало необходимо скомпилировать программу так, чтобы по окончанию работы она сохраняла статистику:
Код: Выделить всё
PROFILER="generate" emerge -1v flac libogg
/var/tmp/fprofile_dir_data/rights.shДалее необходимо поиспользовать FLAC, чтобы накопить статистику в «/var/tmp/fprofile_dir_data/flac/» и «/var/tmp/fprofile_dir_data/libogg/». В результате список файлов должен быть похожим на этот:
Код: Выделить всё
# find /var/tmp/fprofile_dir_data/flac/
/var/tmp/fprofile_dir_data/flac/
/var/tmp/fprofile_dir_data/flac/vorbiscomment.gcda
/var/tmp/fprofile_dir_data/flac/utils.gcda
/var/tmp/fprofile_dir_data/flac/main.gcda
/var/tmp/fprofile_dir_data/flac/getopt1.gcda
/var/tmp/fprofile_dir_data/flac/getopt.gcda
/var/tmp/fprofile_dir_data/flac/.libs
/var/tmp/fprofile_dir_data/flac/.libs/utf8.gcda
/var/tmp/fprofile_dir_data/flac/.libs/replaygain_analysis.gcda
/var/tmp/fprofile_dir_data/flac/.libs/ogg_helper.gcda
/var/tmp/fprofile_dir_data/flac/.libs/md5.gcda
/var/tmp/fprofile_dir_data/flac/.libs/stream_encoder.gcda
/var/tmp/fprofile_dir_data/flac/.libs/format.gcda
/var/tmp/fprofile_dir_data/flac/.libs/iconvert.gcda
/var/tmp/fprofile_dir_data/flac/.libs/lpc.gcda
/var/tmp/fprofile_dir_data/flac/.libs/bitmath.gcda
/var/tmp/fprofile_dir_data/flac/.libs/memory.gcda
/var/tmp/fprofile_dir_data/flac/.libs/picture.gcda
/var/tmp/fprofile_dir_data/flac/.libs/fixed.gcda
/var/tmp/fprofile_dir_data/flac/.libs/stream_encoder_framing.gcda
/var/tmp/fprofile_dir_data/flac/.libs/window.gcda
/var/tmp/fprofile_dir_data/flac/.libs/bitreader.gcda
/var/tmp/fprofile_dir_data/flac/.libs/replaygain.gcda
/var/tmp/fprofile_dir_data/flac/.libs/crc.gcda
/var/tmp/fprofile_dir_data/flac/.libs/bitwriter.gcda
/var/tmp/fprofile_dir_data/flac/.libs/ogg_encoder_aspect.gcda
/var/tmp/fprofile_dir_data/flac/.libs/metadata_iterators.gcda
/var/tmp/fprofile_dir_data/flac/.libs/stream_decoder.gcda
/var/tmp/fprofile_dir_data/flac/.libs/cpu.gcda
/var/tmp/fprofile_dir_data/flac/.libs/seektable.gcda
/var/tmp/fprofile_dir_data/flac/.libs/cuesheet.gcda
/var/tmp/fprofile_dir_data/flac/.libs/file.gcda
/var/tmp/fprofile_dir_data/flac/.libs/replaygain_synthesis.gcda
/var/tmp/fprofile_dir_data/flac/.libs/ogg_decoder_aspect.gcda
/var/tmp/fprofile_dir_data/flac/.libs/metadata_object.gcda
/var/tmp/fprofile_dir_data/flac/conftest.gcda
/var/tmp/fprofile_dir_data/flac/decode.gcda
/var/tmp/fprofile_dir_data/flac/encode.gcda
/var/tmp/fprofile_dir_data/flac/foreign_metadata.gcda
/var/tmp/fprofile_dir_data/flac/local_string_utils.gcda
/var/tmp/fprofile_dir_data/flac/analyze.gcda
# find /var/tmp/fprofile_dir_data/libogg/
/var/tmp/fprofile_dir_data/libogg/
/var/tmp/fprofile_dir_data/libogg/.libs
/var/tmp/fprofile_dir_data/libogg/.libs/framing.gcda
/var/tmp/fprofile_dir_data/libogg/.libs/bitwise.gcda
/var/tmp/fprofile_dir_data/libogg/conftest.gcdaКод: Выделить всё
PROFILER="use" emerge -1v flac liboggПрофилирование «p7zip»
Алгоритм тот же самый, разве что не создаются статистические файлы непосредственно после компиляции в режиме «generate». Тем не менее при последующем запуске статистические данные сливаются и наблюдается ускорение при использовании архиватора после компиляции в режиме «use».
Результаты
Это, наверное, самая сочная часть
Характеристики компьютера: Athlon64 3000+; DDR PC3200 1ГБ; Gentoo AMD64, профиль «no-multilib»; GCC 4.4.4; флаги компиляции стандартные: «-march=athlon64-sse3 -O2 -pipe --param l1-cache-line-size=64 --param l1-cache-size=64 --param l2-cache-size=512»
flac
Измерения для flac'а проводились на цикле распаковки и упаковки альбома с параметром «--best». И вот результат:
12% -- это серьёзно!Режим «стандартный»:
real 2m23.445s 2m20.613s
user 2m14.810s 2m14.430s
sys 0m3.120s 0m3.350s
Режим «use»:
real 2m8.127s 2m6.636s
user 1m58.140s 1m57.760s
sys 0m3.540s 0m3.730s
Профит:
((((2*60+14.810)+(2*60+14.430))/2)-(((1*60+58.140)+(1*60+57.760))/2))/(((2*60+14.810)+(2*60+14.430))/2)*100%=12.38%
p7zip
Ускорение p7zip измерялось подобным образом -- цикл распаковки/упаковки разнородных архивов с параметром «-mx=7»:
В данном случае ускорение не большое, но оно реальное, оно ощутимое и оно есть!Режим «стандартный»:
real 0m47.601s 0m47.982s 0m47.751s
user 0m46.270s 0m46.360s 0m46.070s
sys 0m1.200s 0m1.210s 0m1.310s
Режим «use»:
real 0m45.881s 0m45.907s 0m48.812s
user 0m44.660s 0m44.630s 0m44.580s
sys 0m1.090s 0m1.150s 0m1.060s
Профит:
(((46.270+46.360+46.070)/3)-((44.660+44.630+44.580)/3))/((46.270+46.360+46.070)/3)*100%=3.48%
Мысли
Реально доступным профилирование стало с выходом компилятора версии 4.4.4, потому что именно в этой версии появилась команда «-fprofile-dir», с помощью которой стало возможным указывать отдельные каталоги скопления статистики для разных програм. А теперь ещё версия 4.4.4 в стабильной ветке Gentoo!
«CXXFLAGS» тоже необходимо дополнить командами профилировщика наравне с «CFLAGS». Это утверждение нашло подтверждение в профилировании «p7zip», так как исходный код архиватора состоит в основном из кода на C++.
«-lgcov» не нужен! GCC сам выполняет необходимые действия при линковке объектных файлов, предназначенных для профилирования. Пруф-линк не дам, но утверждение очевидно из выше удавшихся экспериментов и неудавшемся с «qt-core», где «-lgcov» в «LDFLAGS» никак не спасает.
«-fprofile-correction» и «-Wcoverage-mismatch». Вторая команда избавляет от вылета из процесса компиляции при ошибке «несовпадение контрольных сумм исходников», эти ошибки становятся обычными предупреждениями (вместо «error» теперь «warning»). Первая команда («-fprofile-correction») тоже избавляет от ошибки, возникающей в профилировании многопоточных приложений. Конкретнее про эти две команды можно посмотреть в «man gcc». Первую и вторую добавить, возникла необходимость во время профилирования p7zip. Единственным осталось непонятно, почему всё-таки пришлось использовать «-fprofile-correction», ведь архиватор был запущен в один поток на одноядерном процессоре...