Использование gprof с сокетами - PullRequest
5 голосов
/ 02 июня 2010

У меня есть программа, которую я хочу профилировать с помощью gprof. Проблема (похоже) в том, что он использует сокеты. Итак, я получаю такие вещи:

::select(): Interrupted system call

Я решил эту проблему некоторое время назад, сдался и пошел дальше. Но я бы очень хотел иметь возможность профилировать свой код, используя gprof, если это возможно. Что я могу сделать? Мне не хватает опции gprof? Опция сокета? Является ли gprof абсолютно бесполезным при наличии таких системных вызовов? Если так, есть ли жизнеспособная альтернатива?

РЕДАКТИРОВАТЬ: Платформа:

  • Linux 2.6 (x64)
  • GCC 4.4.1
  • gprof 2,19

Ответы [ 2 ]

5 голосов
/ 02 июня 2010

Код сокета должен обрабатывать прерванные системные вызовы независимо от профилировщика, но под профилировщиком это неизбежно. Это значит иметь код вроде.

if ( errno == EINTR ) { ...

после каждого системного вызова.

Взгляните, например, здесь для фона.

1 голос
/ 02 июня 2010

gprof ( вот бумага ) надежна, но она предназначена только для измерения изменений , и даже для этого она измеряет только CPU связанные вопросы. Он никогда не рекламировался как полезный для поиска проблем . Это идея, которую другие люди наслаивали на нее.

Рассмотрим этот метод .

Еще один хороший вариант, если вы не возражаете потратить немного денег, это Увеличение .

Добавлено: Если я могу просто привести вам пример. Предположим, у вас есть иерархия вызовов, в которой Main вызывает A некоторое количество раз, A вызывает B некоторое количество раз, B вызывает C некоторое количество раз, и C ожидает некоторый ввод-вывод с сокетом или файлом, и это в основном все программа делает. Теперь предположим, что число раз, когда каждая подпрограмма вызывает следующую, на 25% больше, чем это необходимо. Поскольку 1.25 ^ 3 составляет около 2, это означает, что запуск всей программы занимает вдвое больше времени, чем необходимо.

Во-первых, поскольку все время тратится на ожидание ввода-вывода, gprof ничего не скажет вам о том, как это время тратится, потому что он смотрит только на «рабочее» время.

Во-вторых, предположим (только для аргумента), что сделал подсчет времени ввода-вывода. Это может дать вам график вызовов, в основном говоря, что каждая подпрограмма занимает 100% времени. О чем тебе это говорит? Ничего больше, чем вы уже знаете.

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

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

...