CachegrindVisualizer 0.3 — 2.5D визуализация схемы работы и профилирование программы

Develar

Новичок
CachegrindVisualizer 0.3 — 2.5D визуализация схемы работы и профилирование программы

CachegrindVisualizer — это кроссплатформенная программа для визуализации файлов в формате Callgrind, в частности, его подмножества используемого Cachegrind. Профайлер Xdebug является совместимым с Cachegrind. Программа написана с использованием AIR — под Linux AIR будет в 2008 году, а Mac OS X поддерживает уже сейчас, но мака у меня нет, так что на данный момент гарантируется работа только под Vista или Windows XP SP2 (поддержка ОС). Версия 0.3 разработана и протестирована в Vista Ultimate Edition с включенным UAC под пользователем с правами администратора. Протестировано с xdebug 2.0.0 и выше (xdebug содержит критическую ошибку — summary (общее время выполнения программы без деструкторов) для сложных программ может быть меньше реального (ответственность за цифры в дочернем ребре 187 % не на мне). Я спрошу у автора xdebug в силу чего так происходит).

Это бета, в силу проблем с памятью при реализованном асинхронном парсинге, пока что он синхронен, но все будет сделано нормально в следующей версии вместе с progress bar.

http://cachegrindvisualizer.googlecode.com/files/CachegrindVisualizer-0.3b1.air

http://code.google.com/p/cachegrindvisualizer/

Версия 0.3 поддерживает AIR Beta 2, в этой версии среды улучшено производительность и управление памятью. Сам CachegrindVisualizer тоже стал кушать в разы меньше RAM благодаря использованию SQLite.

0. Теперь, с версии 0.3, CachegrindVisualizer отличается от WinCacheGrind не только тем, что умеет строить граф, но и поддержкой файлов неограниченного размера (2^53 байт). В версии 0.3 вы можете анализировать и держать открытыми несколько файлов, каждый из которых может весить как минимум 4 ГБ. При этом результаты анализа сохраняются и вы можете как повторно их открыть без необходимости ждать, так и переслать куда-нибудь (переименование файла возможно, программа все равно догадается). Единственный нюанс в поддержке больших файлов в том, что если вы раскроете все дерево вызовов, то, разумеется, оно все и будет загружено в память (в дерево подгружаются не все данные, но наиболее большие - имя функции и имя файла) — но это маловероятно — на большом дереве у вас быстрее устанет рука, чем закончится RAM :). Функция очистки памяти при сворачивании окна/вкладки не реализована, и вряд ли будет, так как на компьютере программиста это только снизит быстродействие (под компьютером программиста я понимаю минимум 2 ГБ RAM).
Отключение режима live mode в следующем выпуске. (Так как при работе с 4 ГБ файлом live mode (то есть режим реального времени) фактически вешает машину, теперь его можно отключить, и самостоятельно после настройки нажать на кнопку, чтобы граф был построен. Данная настройка сохраняется между запусками программы — если кому это не нравится и хочется чтобы она сбрасывалась в значение по умолчанию — включено — пишите, но мне кажется, что это правильное поведение).
Учтите, что поддержка файлов размером до 2^53 байт не протестирована на файлах более 70 МБ, и есть 1 решение в реализации, которые может помешать открытию таких файлов — выбор типа uint (2^32) для идентификации ребра.

1. Добавлена автоматическая регистрация типа файла cachegrind out, то есть, после установки CachegrindVisualizer открытие файла с расширением .cg приведет к открытию его в CachegrindVisualizer (если CachegrindVisualizer уже открыт, то к уже имеющимся вкладкам будет добавлена новая). Спасибо Дерику Ретхансу за расширение параметра конфигурации xdebug.profiler_output_name — для работы этой функции вы должны установить xdebug.profiler_output_name в %t.cg (xdebug.profiler_output_name = %t.cg), спецификатор %t можете заменить на любой другой.
2. Запуск из консоли — абсолютные имена файлов через пробел ("C:\Program Files\CachegrindVisualizer\CachegrindVisualizer.exe" "C:\tmp\1196673587.cg" "C:\tmp\1196673584.cg").
3. Fixed: Для хранения времени (собственного и общего, в мс) был выбран тип uint. Это означало, что время выполнения всегда было равно 0, если оно на самом деле было равно 0,8 или 0,6 мс. Вроде маленькая погрешность, но при суммировании ;) Теперь это Number (Real в SQLite) (в формате Cachegrind используется единица времени равная 10^-4 мс, в целях производительности мы сразу конвертируем в мс, чтобы не делать это каждый раз при выводе).
4. Fixed: Так как xdebug не подсчитывает полное время исполнения деструктора, то мы это делаем сами — в прежних версиях это была только сумма полного времени детей, теперь эта ошибка исправлена — к сумме полного времени детей прибавляется исключительное время деструктора (впрочем, понятно, что это время обычно очень мало и разницы вы не заметите, но мало ли).

От KCacheGrind CachegrindVisualizer отличается тем, что граф не просто проверяет ваш монитор на поддержку цветов радуги, а информирует о времени выполнения узла (модель HSV). Также граф локализуется — форматирование в соответствии с локалью.

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

Что нужно еще доделать:
1) возможность отключения live mode.
2) информирование о текущей загруженной конфигурации.
3) загрузка или сохранение конфигурации должно приводить к выбору этой конфигурации при следующем запуске программы.
4) progress bar

Исходный код в публичном репозитарии, но только CachegrindVisualizer, а не каркаса, который он использует — пока что лениво (будет выложено к новому году с другим opensource проектом) его выкладывать, если кто-то захочет сам скомпилировать — пришлю код каркаса и инструкции по настройке (я не использую жесткую привязку к путям, но переопределен mxml-manifest c flex-config и перегружен Singleton менеджера ресурсов). Если будете использовать Flex Builder — сразу же отключите параметр "Collapse Inherited Members" — ирония в том, что действие этого параметра помимо своего прямого назначения имеет действие и на просмотр массива с количеством элементов в районе нескольких сотен тысяч. Если вы оставите как есть — Collapse — то будет как раз не Collapse — и вы вспомните иной перевод этого слова.

Как пользоваться и более полная информация о программе в первом сообщении в теме посвященной версии 0.1.
Что делать с полученным от программы файлом на языке dot? Его можно просмотреть и удобно с ним работать в ZGRViewer, 2.5D визуализаторе.
1 Установить Graphviz и ZGRViewer.
2 Настроить ZGRViewer.
2.1 Открыли ZGRViewer (в windows это run.bat, в linux run.sh — файл на языке dot кроссплатформен).
2.2 File -> Preferences -> Directories пишем пути к программам, обычно это C:\Program Files\Graphviz\bin\dot.exe (вместо dot для остальных соответственно neato, circo и т. д.), нажимаем Save (да, за юзабилити надо бить, но времени помочь автору ZGRViewer нет) и закрываем окно.
2.3 Правой клавишей мыши щелкаем по файлу: появляется контекстное меню — Открыть с помощью -> Выбрать программу -> выбираем ZGRViewer и ставим галку "Использовать выбранную программу для всех файлов такого типа" -> ОК. Если открылось нормально, переходим к следующем шагу, если нет — разбираемся с путями. Тем кто в windows — поблагодарите архитекторов за ненадобность искать девушку, откройте run.bat и установите переменную ZGRV в абсолютный путь к папке ZGRViewer. Все пути в настройках ZGRViewer должны быть абсолютными, вместе с буквой диска.
Все. Теперь щелкаем по dot файлу и будет сразу открываться ZGRViewer.

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

-~{}~ 13.12.07 21:55:

Сегодня вышел AIR Beta 3, так что это был повод выпустить версию CachegrindVisualizer 0.3 beta 2. Так как особых замечаний не поступило, ничего нового не реализовано.

* анализ стал асинхронным, приложение не замирает во время чтения больших файлов.
* в разы увеличена скорость анализа за счет кеширования страниц БД, цена этого — потребление памяти — максимум 300 МБ (так как данная программа для программистов, не думаю что у кого-то будут проблемы, но если что — пишите, для меня важна скорость и, обладая 3 ГБ памяти, лениво ставить маленький размер кеша).
* fixed: устранена утечка памяти после анализа файла.
* fixed: восстановлена работа фильтра (в первой бете был отключен), делающего граф более чистым — нет дублирующих значений (случай, когда метка острия стрелки равна метке ребра). Метка острия вообще не реализована в KCacheGrind, я и сам забыл зачем оно надо — соотношение собственного/полного когда вызов нескольких детей, а мы хотим знать по каждому ребенку, - где-то в release notes написано :) - скоро наверно напишу документацию объясняющую граф.

Товарищи использующие Mac — как минимум до весны 2008 анализ в CachegrindVisualizer будет медленнее, чем в Windows — это связано с SQLite.
Для больших файлов (от 50 МБ) вторая бета анализирует в 5 раз медленнее чем первая, поэтому эта версия пока не выпущена как стабильная. (Впрочем, заметно это будет только на больших файлах).

-~{}~ 13.12.07 22:05:

http://cachegrindvisualizer.googlecode.com/files/CachegrindVisualizer0.3b2.air

Среду нужно обновить до AIR Beta 3 - http://labs.adobe.com/downloads/air.html

Кстати, не забудьте в настройках ZGRViewer включить antialiasing.

-~{}~ 14.12.07 19:49:

Наверное, утилита никому не нужна, да и я сам ей пока что не пользуюсь, раз никто не послал меня на http://www.xdebug.org/archives/xdebug-dev/1185.html ;)
Зато теперь CachegrindVisualizer единственная утилита под windows и mac визуализирующая профилирование xdebug.

-~{}~ 15.12.07 21:02:

final 0.3 - все что планировалось (кроме progress bar) + возможность указать заголовок для графа (собственно текст и где - снизу или сверху). live mode решен умным таймером - когда вы начнете вводить в numeric stepper желаемый minNodeCost то не сразу будет строиться - в начале ведь может быть 0 :), а подождет 4 секунды (при написании заголовка 2 секунды) и решит - надо строить или пользователь еще не ввел полностью что хотел.
 

phpdev2007

Новичок
гламурнинькая прога, плюс супер инстал и дока, так держать. ха, ха.
 

Wicked

Новичок
Твоя прога + недавнее внедрение поддержки xdebug в PDT прям таки наталкивают меня на освоение xdebug'а заново.
 

Develar

Новичок
Wicked
Если нужно - можно визуализировать и файлы .xt - для этого нужен только xdebug ветки 2.1 dev. В ряде случаев не нужна и тяжела интерактивная отладка и .xt самое то.
 

Wicked

Новичок
Develar
1) я пока не знаю, что такое .xt :)
2) а ты свою прогу Дерику показывал?
3) при установке выдается 2 предупреждения:
Publisher identity: UNKNOWN
The publisher of this application cannot be determined.
System access: UNKNOWN
This application may access your file system and the internet, which may put your computer at risk.

Я то, конечно, доверяю, но среднестатистический юзер может усомниться.
 

Develar

Новичок
Wicked
1) понятно :)
2) не ответил на письмо. в xdebug критическая ошибка в подсчете summary + есть места где происходит арифметическое переполнение - напишу багу, как раз и узнает о программе.
3) О, Adobe тут такую тему развернули - сертификаты, можно купить, а можно и свой без подтверждения издателя сгенерировать. Только AIR в бета-версии, поэтому установщик сертификат пока что игнорирует (то есть при компиляции продукционной версии я сертификат указываю и подписываюсь, но он не используется).
 

Wicked

Новичок
Develar
Посмотрел CGV последней версии. Построенные графики как-то фигово отображают дерево вызовов. Например, показывает вызов xml2array::level2xml() (мой самописный метод) из php::XMLWriter->outputMemory(). И, похоже, совсем никак работает с call_user_func(). Скажи куда можно сдать анализы - вышлю тебе .out и .dot. Светить их каждому встречному не очень охота.
 

Develar

Новичок
Wicked
Вообще-то http://code.google.com/p/cachegrindvisualizer/issues/list , но баг-трекер от google убог, поэтому если нужна приватность - [email protected]
 

Develar

Новичок
принял, сегодня разберусь.

-~{}~ 17.12.07 20:42:

Wicked
Спасибо, исправлено. http://cachegrindvisualizer.googlecode.com/files/CachegrindVisualizer0.3.2dev.air

если нет замечаний, то будет 0.3.2. Кстати, как думаешь - а если убрать обозначение единицы измерения времени? Оно и так всем понятно что в мс?
 

Wicked

Новичок
Спасибо, на высланных тебе файликах еще раз сейчас проверю.

На работе есть особи посерьезней, но это только завтра.

-~{}~ 18.12.07 00:26:

Да, на этом вроде лучше стало, но какая-то беда с Minimal node weight.

Когда ввожу 0.84, нажимаю Refresh, то получается файл размером 10,474байт. Он открывается ZGRViewer'ом замечательно.

Когда ввожу 0.81, нажимаю Refresh, то файл получается размером 4,483байт (хотя должен быть >= 10,474байт). И он залочен. Разлочивается при выходе из CGV, но при открытии в ZGRV, все облака стоят в одну линию.

Сам файлик пошлю письмом.
 

Develar

Новичок
Wicked
Видимо, я идиот в плане юзабилити. Кнопка Refresh запускает повторный анализ файла, а не обновление графа. Сам граф строится автоматически в ответ на ваши действия. Так как отсутствует progress bar, вы пытаетесь открыть файл в момент, когда он пишется...

-~{}~ 17.12.07 21:31:

И кстати, выбирайте русскую локаль, тогда граф будет соответствовать русским ГОСТам, а не USA.
 

Wicked

Новичок
ну помимо кнопки рефреш я еще использовал клик на рутовом элементе дерева - результат одинаковый.

Русская локаль тоже не помогла (если должна была :))
 

Develar

Новичок
надо ждать. и смотреть на рост размера файла %) Но если результат маленький, то строит мгновенно. На этом профайле у меня все быстро. Завтра будет progress bar на построение графа. Если файл был большой - кидайте.

-~{}~ 17.12.07 22:40:

0.3.2
* исправлена критическая ошибка в алгоритме определения иерархии в построителе (спасибо Wicked).
* удалена избыточная хвостовая метка ребра.
* в значительной мере ускорено построение ребер.

В 0.4 будет progress bar на построение графа.
 

Wicked

Новичок
вот сейчас специально запустил с нуля - файл на 4.5кб появляется мгновенно. После этого ничего не происходит.

это в версии 3.2.0dev и 3.2.0.

слишком уж долго оно думает по сравнению со срезом на 0.84, например - несколько минут.

-~{}~ 18.12.07 01:45:

Если файл был большой - кидайте.
файл все тот же.

-~{}~ 18.12.07 01:48:

И еще есть предложение обозначения привести к таким, которые имеются в wincachegrind: например, [cost] threshold вместо minimal node cost. Но это так, мелочи.

-~{}~ 18.12.07 02:06:

Ребутнулся, снес C:\Documents and Settings\!YOUR USER NAME!\Application Data\develar.CachegrindVisualizer". Заработало.

-~{}~ 18.12.07 15:39:

Develar
а в .dot-файлах вызовы не должны повторять очередность, выстраиваясь слева направо? У меня идут вразнобой.

Еще есть предложения...
1) использовать node [style=filled, shape=box];. Мы, все-таки, программисты :)

2) сокращать общий префикс у (require|include)(_once)?'ов, а то уж больно длинно получается.

3) опционально группировать вызовы, где вызывающий и вызываемый одинаковые. Также можно показывать count, sum, min, max, average, mean времени выполнения. А то лично у меня у меня при minimal node weight = 0 выплозают тысячи вызовов к md5, substr, и т.д. (pure-php реализация функции crypt()), которые нахрен никому не нужны по отдельности, тем более что нету никакой возможности понять, при каких аргументах возникли долгие вызовы.

4) опционально форсировать построение _дерева_, а не графа. Несколько лучше для понимания, как программа работает.

5) color можно округлять до сотых или тысячных. Точность типа color="0.6514484407448127 0.4014484407448127 1" никому не нужна, а на размере файла можно сэкономить 15-20% :)

-~{}~ 18.12.07 16:40:

опять нашел багу... высылаю файлики :)
 

Develar

Новичок
Wicked
Терминология определена форматом и официальной документаций. Зачем автор wincachegrind его нарушил, непонятно. Поэтому inclusive, а не cumulative. А минимальная стоимость узла взято из интерфейса KCacheGrind - как того, кто исторически определяет терминологию UI (Min. Node Cost, callgraphview.cpp).

>> а в .dot-файлах вызовы не должны повторять очередность, выстраиваясь слева направо? У меня идут вразнобой.
Ребра перечислены в порядке вызова. Хвост - кто вызвал, Голова - кого вызвали. Если не так, то это ошибка. В этом выпуске она исправлена.

Другие предложения интересные, подумаю. А чем box лучше ellipse?

0.4 beta 1
* в значительной мере ускорена подгрузка данных в дерево.
* ускорен label builder.
* ускорено построение узлов в 2 раза (анализ стал медленее чуть-чуть из-за этого, но он ведь всего один раз).
* отловил в коридоре дизайнера и он подтвердил мои опасения, что повторение на каждом узле того, что время измеряется в мс, бессмыслено.
* реализован progress bar построения графа. Реализован просто, без особо точного измерения - прогресс будет идти не плавно, а скачками. Реализовывать super progress bar который будет очень точно отслеживать прогресс бессмысленно, так как в этом случае он будет пожирать столько ресурсов, что пора будет ему самому вводить progress bar (кто работает в новой ОС от M$ поймет, хотя в M$ этот pb все равно серьезно сбоит) (спасибо Wicked).
* нажатие кнопки "Refresh" останавливает построение графа, если тот в это время строится (спасибо Wicked).
* Теперь, так же как и в KCacheGrind, можно строить "компактные" (то есть результат такой же, что вы в KCacheGrind выбираете "Компактный") графы, без стоимости. Для этого вам доступен новый тип метки — "Нет".
* Таймер ввода minNodeCost изменен с 4 на 2 секунды (то есть приравнен к таймеру вводу graph title).
* fixed: исправлена утечка памяти в построителе.
* fixed: исправлена утечка памяти на вкладке результата (tab), побочным действием утечки было то, что после нажатия кнопки "Refresh" и неизменности анализируемого файла граф строился в момент, когда анализатор еще не вернул результат (спасибо Wicked).
* fixed: недобитый баг определения иерархии (спасибо Wicked).
 

Wicked

Новичок
Develar
Терминология определена форматом и официальной документаций...
Ок, спасибо. Я KCacheGrind просто не видел.

А чем box лучше ellipse?
Объективно: компактнее.
Субъективно тоже больше как-то нравится, когда все прямоугольное.

* отловил в коридоре дизайнера и он подтвердил мои опасения, что повторение на каждом узле того, что время измеряется в мс, бессмыслено.
давай еще знак процента уберем :) Имхо этот пункт зря.

Багов пока не вижу, кроме того, что в ZGRViewer'е все-таки порядок вызовов (горизонтальный) не соблюдается: т.е., например, открыв сейчас в CGV метод Api->processRequest я вижу, что порядок вызовов такой:
Api->startSession,
php::call_user_func,
Api->encodeResult,
Api->sendResponse,
а при просмотре в ZGR облака стоят в таком порядке:
php::call_user_func,
Api->encodeResult,
Api->sendResponse,
Api->startSession.
Файлы выслать?

И можешь рассказать, по какому принципу выбирается цвет объекта? только по self time?

-~{}~ 18.12.07 19:26:

И еще одно предложение появилось. Толщину стрелочек выбирать в зависимости от времени вызова.
 

Develar

Новичок
>> И можешь рассказать, по какому принципу выбирается цвет объекта? только по self time?
http://cachegrindvisualizer.googlecode.com/svn/trunk/source/cachegrindVisualizer/callGraph/builders/Color.as

http://ru.wikipedia.org/wiki/HSV

Узел - inclusive percentage
Ребро - self percentage
Но оперирование понятиями inclusive/self в этом контексте бессмыслено. http://code.google.com/p/cachegrindvisualizer/wiki/ruDescription

-~{}~ 18.12.07 16:35:

>> давай еще знак процента уберем Имхо этот пункт зря.
тогда будут путать что где. Все-таки, в таблицах не пишут единицу измерения, а только в заголовке столбца. И так понятно, что время в мс. ты, просто, наверно, к ним уже привык :)

-~{}~ 18.12.07 16:40:

>> color можно округлять до сотых или тысячных
будет тратиться CPU. ведь таких операций будет 2 * все узлы * все ребра. Пусть уж пишет как есть.

-~{}~ 18.12.07 16:43:

>> 4) опционально форсировать построение _дерева_, а не графа. Несколько лучше для понимания, как программа работает.
Дерево не строится (под деревом я понимаю управляющий элемент Tree слева). Оно подгружается по мере. А для графа теперь есть progress bar - можно теперь понять когда он построился/в ответ на что он автоматически строится.
 

Wicked

Новичок
будет тратиться CPU. ведь таких операций будет 2 * все узлы * все ребра. Пусть уж пишет как есть.
замерял? :)

>> 4) опционально форсировать построение _дерева_, а не графа. Несколько лучше для понимания, как программа работает.
Дерево не строится (под деревом я понимаю управляющий элемент Tree слева). Оно подгружается по мере. А для графа теперь есть progress bar - можно теперь понять когда он построился/в ответ на что он автоматически строится.
Я имел в виду чтобы .dot-файл содержал именно дерево вызовов, как его видно в самом CGV, а не граф. Письмом послал пример одного и того же .out-файла, в виде .dot-графа и .dot-дерева (дерево делал ручками, так что оно в плане циферок не совсем такое, каким должно быть).
 

Develar

Новичок
Товарищу Wicked большое человеческое спасибо за поддержку версий 0.3.1 - 0.4.1, они есть только благодаря его интересным идеям и замечаниям.

0.4 beta 2

* Узел как box, а не ellipse, так компактнее.
* Толщина (linewidth) и размер наконечника (arrowsize) ребра зависит от собственного времени исполнения вызываемой функции, — чем больше, тем толще и больше. Если более 40 %, то толще и больше уже не становится, так как некрасиво.
* Путь в (require|include)(_once)? сокращается. Поддерживается и прямой, и косой слеш, а также их смешивание. Ограничение на длину пути 20 символов (без учета префикса include). Пусть у вас есть include::S:\usr\local\flyti\trunk\classes\cms\tools\viewsListGenerator\Scanner.php, оно будет как include::S:\usr\loc…tGenerator\Scanner.php Имя файла никогда не будет сокращено, оно всегда будет в неизменном виде.
 
Сверху