Инструмент профилирования GPROF имеет неточное время выполнения - PullRequest
0 голосов
/ 20 февраля 2019

Я пытался протестировать свой код cpp с помощью gprof в ubuntu.

Но я обнаружил некоторую ошибку.

Когда gprof вычисляет время выполнения, минимальная единица времени составляет 0,01 секунды.

Например, если время выполнения моей функции в моей программе составляет 0,001 или даже больше, gprof распознает как 0 секунд.

Даже если я выполняю свою функцию тысячу раз, она вычисляется следующим образом: 0 /с + 0 / с ...+ 0 / с = 0 / с

но реальное время работы составляет 1 секунду ...

Итак, я хочу знать, как изменить минимальную единицу времени или рассчитать точное время выполнения.

Пожалуйста, помогите мне:)

И мне не нужны какие-либо рекомендации другого инструмента профилирования

1 Ответ

0 голосов
/ 20 февраля 2019

Этот вопрос является почти дубликатом неточности в выводе gprof , но с небольшим отличием: похоже, он пытается найти узкое место производительности в неправильном месте:

Даже если я выполняю свою функцию тысячу раз, она вычисляется так: 0 / с + 0 / с….+ 0 / s = 0 / s

Это не то, как работает gprof.Gprof производит выборку счетчика программы один раз в T (обычно 0,01 секунды).Он не просто суммирует измерения времени, а скорее опирается на статистику.Вероятность того, что программа, которая занимает 1,00 ЦП, никогда не выбирается из приблизительно 100 сэмплов, которые она должна получить, весьма мала.80 образцов возможно, 120 возможно, 0 практически невозможно.Так что ваша проблема лежит в другом месте.

Gprof имеет много ограничений, как можно видеть при неточности в выводе gprof .Реальная проблема заключается либо в том, что время тратится на ввод-вывод, имеет сложную взаимную рекурсию в общей библиотеке, либо оно пытается использовать те же сигналы, которые использует gprof для выборки кода.

Если вывсе еще настаивают на изменении частоты дискретизации, тогда это кажется теоретически возможным, но это слишком сложно, чтобы того стоить. были претензии , которые переписывали функции profil() или monstartup().Вы можете переопределить их, используя средства компоновки, такие как LD_PRELOAD .Учитывая ограничения gprof, этот путь не стоит, и я не смог найти никакой ссылки на код, который фактически это сделал.

Вот цитата Ника Клифтона по этому вопросу:

Итак, вы можете выбрать:

  1. Измените функцию profil () в вашей ОС.
  2. Напишите свою собственную функцию monstartup () и найдите другой способ генерации временных выборок..

Я пытался изменить интервалы путем взлома интервала SIGPROF:

void set_interval(double seconds)                                                                                                                                              
{                                                                                                                                                                              
      if (seconds <= 0)                                                                                                                                                          
          return;                                                                                                                                                                
      itimerval prev, next;                                                                                                                                                      
      next.it_value.tv_sec = (uint64_t) seconds;                                                                                                                                 

      next.it_value.tv_usec = (uint64_t)(1000000 * (seconds - next.it_value.tv_sec));                                                                                            
      next.it_interval = next.it_value;                                                                                                                                          
      setitimer(ITIMER_PROF, &next, &prev);                                                                                                                                      
}

В Linux, который я пробовал, set_interval(0.1) из main меняет времяинтервал до 1/10 секунды (но сообщает, что неправильно в выводе gprof).Но выполнение set_interval(0.001) не влияет на мою машину, так как самая точная гранулярность установлена ​​на 10 мс.Все, что ниже 10 мс, увеличивается до 10 мс внутри.Чтобы преодолеть это ограничение, прочитайте таймер разрешения 1 мс в соответствии с рекомендациями Linux .

Это становится настолько насмешкой, что я настоятельно рекомендую вам отказаться от этого маршрута и искать другой профилировщик,или выясните, почему gprof не работает для вас как есть.

...