Профилировщики (выборки) все еще лгут в наши дни?

Большая часть моего ограниченного опыта профилирования нативного кода приходится на GPU, а не на CPU, но в будущем я предполагаю некоторое профилирование CPU...

Теперь я только что прочитал это сообщение в блоге:

Как лгут профилировщики: пример gprof и KCacheGrind

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

Мой вопрос: это все еще имеет место сегодня (5 лет спустя)? То есть, выборочные профилировщики (т. е. те, кто не сильно замедляет выполнение) по-прежнему ведут себя так, как раньше gprof (или callgrind без --separate-callers=N)? Или профилировщики в настоящее время обычно записывают весь стек вызовов при выборке?


person einpoklum    schedule 05.04.2018    source источник
comment
Ваш вопрос немного сбивает с толку, потому что второй пример в связанном вопросе включает callgrind, который абсолютно не является профилировщиком выборки: он запускает ваш процесс под виртуальной машиной и может записывать информацию о каждой инструкции/базовом блоке. /функция/что угодно. При этом он замедляет все на порядок и тем самым вносит свой набор проблем и искажений. Однако это не профилировщик выборки.   -  person BeeOnRope    schedule 16.04.2018


Ответы (3)


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

Некоторые цифры в графе вызовов являются оценочными, например, значения времени дочерних элементов и все значения времени в строках вызывающей программы и подпрограммы.

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

Сделано предположение, что среднее время, затрачиваемое на каждый вызов любой функции foo, не коррелирует с тем, кто вызывал foo. Если foo использовал всего 5 секунд, и 2/5 вызовов foo исходили от a, то foo добавляет 2 секунды к времени дочерних элементов a, по предположению.

Что касается KCacheGrind, то с момента написания статьи мало что изменилось. Вы можете проверить журнал изменений и убедиться, что последняя версия была опубликована 5 апреля. , 2013 г., который включает несвязанные изменения. Вы также можете обратиться к комментариям Йозефа Вайдендорфера под статьей (Джозеф — автор KCacheGrind ).

person Hadi Brais    schedule 11.04.2018
comment
Итак, я добавил +1 к вашему ответу, потому что он, ну, отвечает на мой вопрос, но это ужасно. - person einpoklum; 13.04.2018
comment
@einpoklum Вы можете проверить другие профилировщики. В частности, AMD CodeXL от AMD и VTune Amplifier XE от Intel. Есть также ряд инструментов от Microsoft. Я использовал эти инструменты и в основном доволен ими. - person Hadi Brais; 13.04.2018
comment
Являются ли примеры, которые вы размещаете, лучше в том смысле, который я описываю? Являются ли они выборочными профилировщиками? - person einpoklum; 13.04.2018
comment
@einpoklum Да, они есть. Все они поддерживают профилирование на основе выборки. Однако в некоторых случаях может использоваться аппаратура. Я написал серия статей о VTune, и я планирую написать аналогичную серию статей о встроенном профилировщике Visual Studio в ближайшем будущем. Дело в том, что gprof и KCacheGrind действительно устарели и не поддерживаются регулярно. Но те, которые я упомянул, все еще поддерживаются, и они намного более продвинуты. Вот почему я использую их. - person Hadi Brais; 13.04.2018
comment
Стоит отметить, что этот конкретный недостаток присущ не профайлерам сэмплирования, а сэмплерам вроде gprof, которые записывают ограниченную информацию о стеке вызовов. В случае gprof вы на самом деле ищете гибридный сэмплер, который записывает информацию о вызывающем/вызываемом абоненте с использованием инструментов, но затем периодически записывает ПК с сэмплированием. Он объединяет их в тип поддельного вывода стека вызовов, используя предположения, которые вы выделили выше, которые могут быть произвольно ошибочными. - person BeeOnRope; 16.04.2018
comment
Однако этот дизайн не является стандартным или даже обычным для большинства профилировщиков выборки. Типичное профилирование выборки может захватить весь стек вызовов в выборке (perf делает, если вы попросите об этом). Это позволяет полностью избежать этой проблемы. - person BeeOnRope; 16.04.2018

Нет, многие современные профилировщики выборки не имеют проблемы, описанной в отношении gprof.

На самом деле, даже когда это было написано, конкретная проблема на самом деле была скорее причудой того, как gprof использует сочетание инструментария и выборки, а затем пытается реконструировать гипотетический график вызовов на основе ограниченного числа вызывающих/вызываемых абонентов. информацию и объединить ее с дискретизированной информацией о времени.

Современные профилировщики выборки, такие как perf, VTune и различные профилировщики для языков, которые не компилируются в собственный код, могут захватывать полный стек вызовов с каждой выборкой, что обеспечивает точное время в отношении этой проблемы. В качестве альтернативы вы можете выполнить выборку без сбора стеков вызовов (что значительно снижает стоимость выборки), а затем представить информацию без какой-либо информации о вызывающем/вызываемом абоненте, которая все равно будет точной.

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

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

person BeeOnRope    schedule 16.04.2018

Если вы заметили, я добавил несколько комментариев к тому сообщению, на которое вы ссылаетесь, но дело не только в том, что профилировщики дают вам неверную информацию, а в том, что люди обманывают себя относительно того, что такое производительность на самом деле.

Какова твоя цель? А) выяснить, как сделать программу максимально быстрой? Или для Б) измерения времени, затрачиваемого различными функциями, в надежде, что это приведет к А? (Подсказка — это не так.) Вот подробный список проблем.

Для иллюстрации: вы могли бы, например, вызвать маленькую невинно выглядящую маленькую функцию где-нибудь, которая случайно вызывает девять ярдов системного кода, включая чтение .dll для извлечения строкового ресурса, чтобы интернационализировать его. Это может занимать 50% времени настенных часов и, следовательно, находиться в стеке 50% времени настенных часов. Покажет ли это вам «CPU-profiler»? Нет, потому что практически все эти 50% приходится на ввод-вывод. Вам нужно много образцов стека, чтобы точно знать с точностью до 3 знаков после запятой, сколько времени это занимает? Конечно, нет. Если бы у вас было только 10 образцов, это было бы на 5 из них, плюс-минус. Как только вы узнаете, что подростковая рутина — это большая проблема, значит ли это, что вам не повезло, потому что ее написал кто-то другой? Что, если бы вы знали, что это за строка, которую он ищет? Действительно ли он должен быть интернационализирован настолько, что вы готовы заплатить за это вдвое медленнее? Вы понимаете, насколько бесполезны измерения, когда ваша настоящая проблема состоит в том, чтобы качественно понять, что требует времени?

Я мог бы продолжать и продолжать подобные примеры...

person Mike Dunlavey    schedule 12.04.2018
comment
Чтобы ответить на ваш встречный вопрос: я хочу понять, как ведет себя мой код и какая работа выполняется в течение какого времени. В вашем примере профилировщик ЦП с достаточно обширным сбором информации показал бы мне, какие системные вызовы (и, возможно, какие общие комбинации частичных параметров для этих вызовов) занимают много времени - и более того, какие строки кода выполняют эти системные вызовы. ; и тогда я могу понять, что трачу половину своего времени на чтение интернационализированных строк из файлов. Зная это, я либо покончу с этим, либо решу, что хочу сделать... - person einpoklum; 13.04.2018
comment
... что-то о (например, перемещение этой работы в отдельный поток или как-то кэширование этих строк и т. д.) - person einpoklum; 13.04.2018
comment
И вам нужно много образцов стека, чтобы точно знать с точностью до 3 знаков после запятой, сколько времени это занимает? - вы неправильно понимаете. Мне нужно много образцов стека, чтобы с точностью до первого десятичного знака знать, сколько времени занимают разные состояния стека, поскольку пространство состояний намного больше. - person einpoklum; 13.04.2018
comment
@einpoklum: Возможно, эта ссылка поможет объяснить, как это работает статистически. - person Mike Dunlavey; 13.04.2018