В разработке программного обеспечения профилирование («профилирование программы», «профилирование программного обеспечения») — это форма динамического анализа программы , которая измеряет, например, пространственную (память) или временную сложность программы , использование определенных инструкций или частоту и продолжительность вызовов функций. Чаще всего информация профилирования служит для оптимизации программы и, в частности, для повышения производительности .
Профилирование достигается путем инструментирования исходного кода программы или ее двоичной исполняемой формы с помощью инструмента, называемого профилировщиком (или профилировщиком кода ). Профилировщики могут использовать ряд различных методов, таких как методы, основанные на событиях, статистические, инструментальные и методы моделирования.
Профилировщики используют широкий спектр методов для сбора данных, включая аппаратные прерывания , инструментирование кода , моделирование набора команд , перехваты операционной системы и счетчики производительности .
Инструменты анализа программы чрезвычайно важны для понимания поведения программы. Компьютерным архитекторам нужны такие инструменты, чтобы оценить, насколько хорошо программы будут работать на новых архитектурах . Разработчикам программного обеспечения нужны инструменты для анализа своих программ и определения критических участков кода. Авторы компиляторов часто используют такие инструменты, чтобы узнать, насколько хорошо работает их алгоритм планирования инструкций или предсказания ветвей ...
— АТОМ, ПЛДИ
Результатом профилирования может быть:
/* ------------ источник ------------------------- количество */ 0001 ЕСЛИ X = "А" 00550002 ТОГДА ДЕЛАЙ 0003 ДОБАВИТЬ 1 к XCOUNT 00320004 ЕЩЕ0005 ЕСЛИ X = "B" 0055
Профилировщик можно применять к отдельному методу или в масштабе модуля или программы, чтобы выявить узкие места в производительности, сделав очевидным долго выполняющийся код. [1] Профилировщик можно использовать для понимания кода с точки зрения синхронизации с целью его оптимизации для обработки различных условий выполнения [2] или различных нагрузок. [3] Результаты профилирования могут быть обработаны компилятором, который обеспечивает оптимизацию на основе профиля . [4] Результаты профилирования можно использовать для разработки и оптимизации отдельного алгоритма; Примером может служить алгоритм сопоставления подстановочных знаков Краусса . [5] Профилировщики встроены в некоторые системы управления производительностью приложений , которые объединяют данные профилирования, чтобы обеспечить понимание рабочих нагрузок транзакций в распределенных приложениях. [6]
Инструменты анализа производительности существовали на платформах IBM/360 и IBM/370 с начала 1970-х годов, обычно основанные на прерываниях таймера, которые записывали слово состояния программы (PSW) через заданные интервалы таймера для обнаружения «горячих точек» при выполнении кода. [ нужна цитация ] Это был ранний пример выборки (см. ниже). В начале 1974 года симуляторы с набором команд позволяли осуществлять полную трассировку и другие функции мониторинга производительности. [ нужна цитата ]
Анализ программ на основе профайлера в Unix восходит к 1973 году [7] , когда системы Unix включали в себя базовый инструмент , prof
в котором перечислялись все функции и время выполнения программы, которое они использовали. В 1982 году gprof
эта концепция была расширена до полного анализа графа вызовов . [8]
В 1994 году Амитабх Шривастава и Алан Юстас из Digital Equipment Corporation опубликовали статью, описывающую ATOM [9] (Инструменты анализа с OM). Платформа ATOM преобразует программу в собственный профилировщик: во время компиляции она вставляет в программу код для анализа. Этот вставленный код выводит данные анализа. Этот метод — изменение программы для анализа самой себя — известен как « инструментация ».
В 2004 году статьи The gprof
и ATOM вошли в список 50 наиболее влиятельных статей PLDI за 20-летний период, закончившийся в 1999 году. [10]
Плоские профилировщики вычисляют среднее время вызовов на основе вызовов и не разбивают время вызовов в зависимости от вызываемого абонента или контекста.
Профилировщики графа вызовов [8] показывают время вызовов и частоту выполнения функций, а также задействованные цепочки вызовов в зависимости от вызываемого абонента. В некоторых инструментах полный контекст не сохраняется.
Профилировщики, чувствительные к вводу [11] [12] [13], добавляют дополнительное измерение к плоским профилировщикам или профилировщикам на основе графа вызовов, связывая показатели производительности с особенностями входных рабочих нагрузок, такими как размер входных данных или входные значения. Они создают диаграммы, которые характеризуют, как производительность приложения масштабируется в зависимости от входных данных.
Профайлеры, которые сами по себе являются программами, анализируют целевые программы, собирая информацию об их выполнении. В зависимости от детализации данных и того, как профилировщики собирают информацию, они классифицируются на профилировщики, основанные на событиях, или статистические. Профилировщики прерывают выполнение программы для сбора информации, что может привести к ограниченному разрешению измерений времени, к которым следует относиться с недоверием. Базовые профилировщики блоков сообщают о количестве машинных тактов , посвященных выполнению каждой строки кода, или о времени, основанном на их суммировании; тайминги, сообщаемые для каждого базового блока, могут не отражать разницу между попаданиями и промахами в кэше . [14] [15]
Перечисленные здесь языки программирования имеют профилировщики на основе событий:
Некоторые профилировщики работают путем выборки . Профилировщик выборки проверяет стек вызовов целевой программы через регулярные промежутки времени, используя прерывания операционной системы . Профили выборки обычно менее точны и конкретны в числовом отношении, но позволяют целевой программе работать практически на полной скорости.
Полученные данные являются не точными, а статистическим приближением. «Фактическая величина ошибки обычно превышает один период выборки. Фактически, если значение в n раз превышает период выборки, ожидаемая ошибка в нем равна квадратному корню из n периодов выборки». [16]
На практике профилировщики выборки часто могут предоставить более точную картину выполнения целевой программы, чем другие подходы, поскольку они не так навязчивы целевой программе и, следовательно, не имеют такого большого количества побочных эффектов (например, на кэши памяти или инструкции). конвейеры декодирования). Кроме того, поскольку они не так сильно влияют на скорость выполнения, они могут обнаруживать проблемы, которые в противном случае были бы скрыты. Они также относительно невосприимчивы к переоценке стоимости небольших, часто называемых процедур или «жестких» циклов. Они могут показывать относительное количество времени, затраченное в пользовательском режиме, по сравнению с прерываемым режимом ядра, например, на обработку системных вызовов .
Тем не менее, код ядра для обработки прерываний влечет за собой незначительную потерю циклов ЦП, перенаправление использования кэша и неспособность различать различные задачи, происходящие в бесперебойном коде ядра (активность в микросекундном диапазоне).
Специальное оборудование может пойти дальше: интерфейс JTAG ARM Cortex-M3 и некоторых последних процессоров MIPS имеет регистр PCSAMPLE, который производит выборку счетчика программ действительно необнаружимым образом, позволяя ненавязчиво собирать плоский профиль.
Некоторые широко используемые [17] статистические профилировщики для Java/управляемого кода — это AQtime [18] от SmartBear Software и CLR Profiler от Microsoft . [19] Эти профилировщики также поддерживают профилирование собственного кода вместе с Shark (OSX) от Apple Inc. , [20] OProfile (Linux), [21] Intel VTune и Parallel Amplifier (часть Intel Parallel Studio ) и Oracle Performance . Анализатор , [22] и другие.
Этот метод эффективно добавляет в целевую программу инструкции для сбора необходимой информации. Обратите внимание, что инструментирование программы может привести к изменениям производительности и в некоторых случаях может привести к неточным результатам и/или ошибкам . Эффект будет зависеть от того, какая информация собирается, от уровня детализации временных данных, а также от того, используется ли базовое профилирование блоков в сочетании с инструментами. [23] Например, добавление кода для подсчета каждого вызова процедуры/подпрограммы, вероятно, будет иметь меньший эффект, чем подсчет количества выполнений каждого оператора. Некоторые компьютеры имеют специальное оборудование для сбора информации; в этом случае влияние на программу минимально.
Инструментирование является ключом к определению уровня контроля и временного разрешения, доступного профилировщикам.