Определение оптимальных конфигураций запуска анализатора корректности Intel® Parallel Inspector

Создать новую статью

11.09.2009 13:00


Статья содержит описание исследования по поиску оптимальных конфигураций запуска Intel® Parallel Inspector. Intel® Parallel Inspector - это инструмент, позволяющий обнаруживать в приложении ошибки работы с памятью или потоками. Помимо возможности запуска из MS Visual Studio с выбором уровня анализа, проверку любого исполняемого файла можно производить запуском Parallel Inspector из командной строки, вручную прописывая все желаемые параметры одного из видов анализа. Этим я и воспользовалась для проведения исследования, которое заключалось в нахождении зависимости времени анализа от тех или иных параметров запуска. В качестве итога предложен метод предсказания времени анализа на основании указанных пользователем параметров. Также сформирован набор рекомендуемых конфигураций, учитывающий баланс между глубиной и временем анализа.

О чем и зачем?

В чем собственно проблема? Что такое оптимальные конфигурации запуска? Почему бы не анализировать приложение как можно полнее и глубже? Дело в том, что время анализа приложения может в несколько тысяч раз превышать время работы самого приложения. Минутное приложение может анализироваться больше суток.

Хочется дать пользователю гибкий механизм, который позволил бы балансировать между глубиной анализа и затраченным на этот анализ временем. Кому-то нужно знать об очевидных ошибках, но сразу, быстро. Кто-то готов ждать сколько угодно, но быть уверенным на все 100% в своем приложении.

С чего я начала? Подобрала базу приложений, потом долго-долго собирала (написав скрипт) статистические данные, смотрела, выискивала закономерности, в конце концов, сформировала рекомендации, те самые оптимальные (на мой взгляд) конфигурации. Сразу отмечу, что задача не состояла в том, чтобы следить за "качеством" результа работы Intel® Parallel Inspector (соответственно за количеством обнаруженных ошибок), вопрос заключался в нахождении зависимости time overhead от указанных параметров запуска. Но, обо всем по порядку...

Зоопарк приложений

Для исследований был использован ряд самых разнообразных приложений. Среди них были и приложения, требующие выделения большого числа ресурсов и содержащие глубокие рекурсии, сложные вычислительные приложения, парочка компрессоров данных. Особое внимание уделялось многопоточным приложениям. Большинство используемых приложений, так называемые "спеки" (SPEС), предназначены для измерения производительности компьюьтеров. Время работы приложений варьировалось от нескольких сотых секунды до нескольких сот секунд.

Полным перебором?

Первая мысль была, взять и перебрать все параметры, во всех комбинациях, на всех отобранных приложениях! Хорошая мысль. Количество запусков определялось набором параметров обоих видов анализа, что есть в Intel® Parallel Inspector. Напомню, есть Check Threading Errors и Check Memory Errors. Анализ ошибок работы с памятью осуществляется комбинацией из пяти параметров и одного «независимого». Анализ ошибок работы с потоками - комбинацией из восьми параметров. В каждом из видов анализа можно регулировать значение глубины стека.

Для анализа ошибок работы с памятью число возможных сочетаний параметров равно 1056, для анализа ошибок работы с потоками - более 8 тысяч. Если это помножить на количество моих приложений и учесть что часть испытаний будет неизбежно долгой, то... это годы. Например, чтобы собрать статистику по всем видам анализа односекундного приложения, потребуется 26 часов 47 минут 57 секунд, примерно. Что уж говорить о сборе статистических данных, где требуются более существенные, продолжительные приложения.

Чтобы не успеть состариться ко времени окончания сбора статистики, я решила ограничиться рядом «влиятельных» параметров. Откуда они взялись? В ходе первого этапа испытаний обнаружилось существование неких уровней анализа, характеризующихся четким рядом комбинаций параметров. Влияние остальных на время анализа если и имело место, то было настолько мало и неявно, что его (это влияние) легко было принять за погрешность измерений или наоборот.

Подумала, посоветовалась с разработчиками Parallel Inspector (уникальный шанс общаться с авторами, информация из первых рук!) и решила собирать статистику только для этих «уровней». Это позволило сократить время сбора статистических данных, так как число комбинаций параметров стало значительно меньше. Для анализа ошибок работы с памятью это число составило 288 комбинаций, для потокового анализа - 188 комбинаций. Кроме того, данные стали, что называется «обозримыми».

Не прошло и полгода

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

Overhead time = [Initialization cost] + Application run time × [Level multiplier] × [Stack multiplier] , где

Overhead time - время анализа приложения,

[Initialization cost] - «цена» инициализации, время необходимое на «разогрев» коллектора (создание директорий для хранения выходных данных Intel Parallel Inspector, подключения некоторых библиотек и т.д.),

Application run time - чистое время работы приложения,

[Level multiplier] - коэффициент умножения, зависящий от конкретного сочетания заданных параметров того или иного вида анализа

[Stack multiplier] - коэффициент умножения, зависящий от заданного значения глубины стека

Для вычисления цены инициализации ([Initialization cost]) было использовано минимальное по содержанию приложение, которое мы можем себе позволить - « void main() {} ». Собрав статистику для такого нехитрого приложения и зная чистое время выполнения программы (0.016 секунд) было нетрудно вычислить искомую величину. С учетом погрешностей измерений, в среднем Initialization cost = 3.5 секунды.

Следующего участника формулы, влияние изменения глубины стека на время анализа приложения ([Stack multiplier]), можно оценить на рисунке 1.

Влияние изменения глубины стека на время анализа приложения

Рисунок 1

Пожалуй, следует пояснить график. Вертикальная ось - время анализа. Ось, направление которой указывают стрелочки - изменение глубины стека, а третья - просто перебор всех возможных комбинаций параметров соответствующего вида анализа. Насколько можно заметить, зависимости от глубины стека либо нет, либо она неуловимо мала. После проведения ряда замеров были получены значения, подтверждающие, что зависимость небольшая, но есть. Среднее значение увеличения времени анализа при максимально выбранной глубине стека (32) составляет 10%. Полученная зависимость линейно аппроксимирована и представлена в виде показательной функции с основанием 1.003. Таким образом, при возведении данного основания в степень значения выбранной глубины стека при глубине, равной 32, будет получено увеличение времени анализа на 10% . Что подтверждается статистическими данными.

Теперь самое сложное - коэффициент, зависящий от конкретного сочетания параметров ([Level multiplier]). Ничего другого, кроме как предложить показывать диапазон возможного замедления, я не нашла. В каждом конкретном случае замедление сильно зависит от природы приложения, поэтому диапазоны столь широкие. На рисунке 2 приведены «показатели» уровней и диапазоны коэффициентов умножения для определения времени анализа при переходе от run time приложения на какой-либо уровень.

Рисунок 2

Еще раз, данные статистические, испытания включали в себя все возможные комбинации параметров, в том числе и отсутствие их (all false). Отключение всех параметров, то есть отсутствие какого-либо анализа не должно было нас заинтересовать, если бы не один момент. В Memory analysis это время не минимально. Это происходит по одной простой причине. Для анализа ошибок работы с памятью используется два отличных друг от друга коллектора. Один из них несколько «легче» и быстрее другого. Его запуск определяется включением одного из параметров «leak check only» или «leak check on exit». Если же ни один из этих параметров не включен - запускается другой более «тяжелый» и медленный коллектор. Стоит отметить, что сама по себе комбинация параметров all false практического значения для пользователя не имеет, следовательно, данный уровень можно убрать из итогового списка.

Камушек в огород Intel

Разрешите мне сравнить теперь то, что предложил нам Intel в анализаторе корректности Parallel Inspector в качестве базовых уровней и то, что измерила я. Оценки time overhead несколько отличаются друг от друга. Обещанный разработчиками overhead не должен превышать 160х для memory анализа и 320х для threading анализа. Но что же мы видим? Более 1700х и 3500х соответственно для каждого из видов анализа! Где правда и кому верить? Дело в том, что самые высокие коэффициенты замедления характерны для приложений, время выполнения которых мало. Пользователь не успеет заскучать в ожидании окончания анализа своего короткого приложения. Зато для достаточно продолжительных по времени выполнения приложений эти коэффициенты все-таки стремятся к указанным разработчиками значениям. Этот нехитрый маркетинговый ход позволяет пользователю не испугаться потратить полжизни на анализ, хотя, конечно, и не позволяет достоверно представить время, необходимое для анализа.

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

Рисунок 3

В связи с доказанным отсутствием сильного влияния глубины стека на time overhead, я бы предложила объединить второй и третий уровни каждого из видов анализа, так как друг от друга они отличаются только числовым значением глубины стека.

Кроме того, можно предложить выделить в отдельный уровень включение параметра «leak check on exit» анализа ошибок работы с памятью, но не столько в связи с разницей в коэффициентах умножения, сколько по причине влияния глубины стека на предыдущий уровень, характеризующийся включением «leak check only». Как? Еще минуту назад утверждалось, что глубина стека не оказывает сильного влияния на время анализа приложения. Действительно, не влияет, во всех случаях кроме случая включения одного маленького, но очень гордого параметра. Он с самого начала обособлен от остальных. «Leak check only» параметр memory анализа. Во-первых, его включение полностью отрицает влияние других параметров. Во-вторых, тип анализа, проводимого при включении этого параметра, реагирует на значение глубины стека.

Вывод

Собственно, основные выводы изложены в предыдущем абзаце. Здесь я хочу подчеркнуть, что методика расчета time overhead все-таки была сформирована за время летней практики в Intel. Теперь вы можете, вооружившись калькулятором, попытаться подсчитать предположительное время анализа в зависимости от определенного вами набора параметров. Но не стоит забывать о том, что оно целиком и полностью зависит от самого приложения, анализ которого проводится.

Об авторе

Новожилова Анастасия Григорьевна, студентка Нижегородского Государственного Технического Университета, проходила стажировку в рамках летней школы Intel в славном городе Нижний Новгород. Помимо огромного удовольствия от участия в летней школе я получила неоценимый опыт работы в команде первоклассных специалистов! Для меня лично эта стажировка стала отличным началом моей карьеры программиста.