Как найти узкие места производительности в С++-коде
У меня есть серверное приложение, написанное на С++ и развернутое в Cent OS. Я не написал какую-либо часть его кода, но мне нужно оптимизировать его производительность. Его текущая производительность приемлема для небольшого количества пользователей, но когда количество пользователей значительно увеличивает производительность сервера.
Существуют ли какие-либо инструменты, методы или лучшие практики, чтобы выяснить узкие места?
Ответы
Ответ 1
Обычно люди используют профилировщики для определения узких мест в производительности. Более ранние SO-запросы, запрашивающие С++-профиляторы, здесь и здесь (в зависимости от используемой операционной системы и компилятора), Для Linux люди обычно используют gprof только потому, что он поставляется с системой.
Ответ 2
Вы начнете с создания среды тестирования производительности, если у вас ее нет.
- Оборудование производственного класса. Если у вас нет бюджета для этого, вы также можете отказаться.
- Программа драйвера или аппаратные устройства, которые с высокой скоростью генерируют такой же трафик, как и быстрее, чем производство. В зависимости от вашего протокола и прецедента это может быть легко или сложно. Один из методов состоит в том, чтобы отбирать некоторые запросы от производства и воспроизводить их, но это может дать нереалистичные результаты, так как это даст более высокие показатели попадания в кеш.
- Окружающая инфраструктура похожа на продукцию, которую вы можете разумно получить
Затем воспроизведите проблему, как она существует в производстве. После того, как вы это сделали, используйте профайлер и т.д., Как предложили другие.
Ответ 3
Это работает, в обязательном порядке.
Ответ 4
Мне нравится, MIke Dunlavey ответить выше (так что вспять его, если вы вскрываете мой)
Я хотел бы уточнить, кто-то спешит двумя способами:
- Быстрый выбор для
gcc
пользователей для выбора в gstack
- самоконтроль с
SIGALRM
в сочетании с backtrace
(управляемый вашим собственным таймером).
Всего несколько дней назад я сделал что-то вроде этого
# while true; do gstack $MYPID; sleep 2; done | logger $PARAMS
используя PARAMS, которые идут с моими правилами маршрутизации syslog, чтобы журналы моего приложения были перемешаны с помощью стеков (не идеальный состав с событиями)
Результаты были на носу, они указали мне на область, которая, как я думал, может быть проблемой вообще, но была моим узким местом из-за неправильного использования ссылки в tr1:: bind
В методе тревоги будьте осторожны с тем, что вы делаете в сигнале, не используйте ничего, что выделяет память (нет cout/cerr/boost, и используйте только простые форматы (т.е. "% 08X" с printf)