Аналізатор продуктивності
Ви могли б чути про Аналізатор Продуктивності (названий “CPU Usage Analyzer” (Аналізатор використання центрального процесора (ЦП)) у Qt Creator 4.6 і раніше). Йдеться про профільування програм з використанням чудового інструменту «perf» у Linux. Ви можете використовувати його локально в Linux – базовій настільній системі або на різних пристроях, що вбудовуються. "perf" може записувати різні події, які виникають у вашому додатку. До них відносяться помилки (втрати) в кеші, завантаження пам'яті, перемикачі контексту або одне з найпоширеніших циклів CPU, які періодично записують зразок стека після проходження ряду циклів CPU. Отриманий профіль показує, які функції у вашій програмі займають більшість циклів процесора (CPU). Це найпомітніший приклад використання Аналізатора Продуктивності, принаймні досі.
Створення точок трасування
З Qt Creator 4.7 ви також можете записувати події для точок трасування, і якщо ваші точки трасування відповідають певній умові надання імен, Qt Creator буде знати, що вони означають розподіл ресурсів або звільнення цих ресурсів. Тому, встановлюючи точки трасування на malloc, free та friends, ви можете відстежувати ваші програми безліччю способів. Щоб допомогти вам налаштувати точки трасування для цього варіанта використання, Qt Creator пакує скрипт оболонки (сценарій командного процесора), який ви можете виконати, і запитує його запуск. Спочатку відкрийте свій проект та виберіть конфігурацію запуску, яку ви хочете вивчити. Потім просто виберіть кнопку "Створити точки трасування ..." у рядку заголовка аналізатора, і ви отримаєте:
Як це працює?
Для того, щоб непривілейовані користувачі могли використовувати точки трасування, скрипт повинен зробити ядро налагодження та трасування файлових систем доступними для всіх користувачів системи. Ви повинні робити це лише у контрольованих середовищах. Скрипт зазвичай працює для 32-бітних ARM-систем та 64-бітних x86-систем. 64-бітові ARM-системи можуть приймати точки трасування лише якщо ви використовуєте ядро Linux версії 4.10 або вище. Щоб встановити точки трасування на 32-бітових системах x86, вам потрібно мати символи налагодження для вашої стандартної бібліотеки. Скрипт спробує створити точки трасування для будь-якого двійкового (бінарного) коду, який називається libc.so.6, що знаходиться у /lib. Якщо у вас встановлено 64-розрядну систему з додатковими 32-розрядними бібліотеками, вона спробує створити точки трасування для обох підструктур. Це може бути успішним лише для однієї з них. Це не проблема, якщо ваша програма націлена на підструктуру, для якої скрипту вдалося встановити точки трасування.
Пошук та усунення несправностей
Якщо скрипт трасування точок виходить, завершується з помилкою, ви можете перевірити, що ваше ядро було скомпільоване з увімкненою опцією CONFIG_UPROBE_EVENT. Без цієї опції ядро не підтримує точки трасування користувача. Усі 32-розрядні ARM-зображення, що поставляються з Qt для створення пристроїв (Device Creation), мають цю опцію з версії 5.11. У більшості дистрибутивів Linux, призначених для використання на настільних комп'ютерах, використовується CONFIG_UPROBE_EVENT.
Використання точок трасування для профілювання
Після створення точок трасування вам потрібно повідомити Qt Creator'у використовувати їх для профілювання. Для цього в налаштуваннях аналізатора продуктивності є зручна клавішна комбінація. Ви можете отримати доступ до настройок або для конкретного проекту в налаштуваннях «Запуск» у режимі «Проекти», або в глобальному масштабі з «Параметри» в меню «Інструменти». Просто виберіть "Використовувати точки трасування". Потім Qt Creator замінить ваше поточне налаштування подій на будь-які точки трасування, які вона виявить у цільовій системі, і обов'язково записуйте зразок щоразу, коли трапляється точка трасування.
Після цього вам потрібно натиснути кнопку "Пуск" на панелі інструментів профільника, щоб профілювати програму. Після завершення програми Qt Creator збирає дані профілю та відображає його.
Інтерпретування даних
Найпростіший спосіб обчислити, які фрагменти коду витрачають багато пам'яті, це подивитися на flame графік. Щоб отримати найбільш значущі результати, виберіть “Peak Usage” у верхньому правому куті. Це покаже вам цей графік, відсортований за накопиченим обсягом пам'яті, виділеним цими ланцюжками викликів. Розглянемо цей приклад
Висновки
Як ви бачите тут - це профіль Qt Creator, що завантажує велике QML-трасування в QML Profiler. Профайлер QML використовує багато пам'яті, коли відображає великі трасування. Цей профіль розповідає деякі подробиці про використання. Між іншим, цей полум'яний графік говорить нам, що:
- Моделі для графіків Timeline, Statistics та Flame споживають близько 43% пікової пам'яті. TimelineTraceManager::appendEvent(...) відправляє події в різні моделі та викликає виділення.
- З них найбільша частина – 18,9% для моделей діапазону Timeline. Категорії JavaScript, Bindings та Signal Handling – це моделі діапазону. Вони зберігають вектор додаткових даних із записом кожного такого діапазону. Ви можете побачити QArrayData::allocate(...), який виділяє пам'ять цих векторів.
- Рендеринг Timeline споживає більшу частину пам'яті, не виділеної для базових моделей. Зокрема, Timeline::NodeUpdater::run() відображається у всіх інших трасуваннях стека. Ця функція відповідає за заповнення геометрії, яка використовується для відображення категорій тимчасової шкали (Timeline). Тому QSGGeometry::allocate(...) є тим, що ми бачимо як пряму причину для розподілу. Це також говорить нам, чому QML профілює графічну карту з декількома гігабайтами пам'яті для відображення таких трасувань.
Можливі оптимізації
Звідси легко пропонувати ідеї для оптимізації функцій, що порушують нормальну роботу. Ми могли б переглянути, чи дійсно нам потрібні всі дані, що зберігаються в різних моделях, або ми могли б тимчасово зберегти їх на диск, поки вони не потрібні. Переважна кількість виділеної геометрії також говорить про те, що поріг для об'єднання сусідніх подій у щільне трасування може бути занадто низьким. Нарешті ми могли б звільнити геометрію в основній пам'яті, як тільки ми завантажимо її на GPU.
Накладні витрати трасування
Профілювання кожного виклику malloc () та free () у додатку призведе до значних втрат. Ядро, швидше за все, не зможе йти в ногу з часом і відкине деякі зразки. Тим не менш, залежно від вашого конкретного робочого навантаження результуючий профіль все ж таки може дати вам важливу інформацію. Іншими словами: якщо ваша програма виділяє величезну кількість пам'яті тільки в декількох викликах для malloc(), одночасно виділяючи і відпускаючи невелику кількість на високій частоті, ви можете пропустити виклики malloc(), що цікавлять вас, оскільки ядро може відкинути їх. Однак, якщо проблемні виклики malloc() складають більший відсоток від загальної кількості викликів, ви, ймовірно, зловите хоча б деякі з них. У будь-якому випадку Qt Creator надасть вам абсолютні числа для розподілу, випуску та використання максимальної пам'яті. Ці цифри відносяться до зразків perf, які фактично повідомляються, а отже, не зовсім точні. Інші інструменти повідомлятимуть про різні цифри.
Спеціальні функції виділення пам'яті
Крім того, є функції розподілу пам'яті, які ви не можете використовувати для профілювання таким чином. Зокрема posix_memalign() не повертає результуючий показник у стек або регістр. Тому ми не можемо записати його з точкою трасування. Крім того, розподільники пам'яті, які ви можете використовувати для своєї програми, не обробляються точками трасування за замовчуванням. Наприклад, розподільник хіп ("купа") JavaScript, що використовується QML, не відображатиметься у профілі. Хоча для цього конкретного випадку можна використовувати QML Profiler. Також існують різні заміни для стандартних функцій розподілу C, наприклад, jemalloc або tcmalloc. Якщо ви хочете відстежувати їх, вам необхідно визначити пункти трасування користувача
Висновок
Профіль використання пам'яті за допомогою Аналізатора Продуктивності Qt Creator - це простий і швидкий спосіб отримати важливі відомості про використання пам'яті вашою програмою. Він працює в ящику для будь-яких цілей Linux, що підтримуються Qt Creator. Ви можете одразу переглянути отримані дані профілю у загальнодоступному графічному інтерфейсі (GUI) без подальшої обробки або передачі даних. Інші інструменти можуть надавати більш точні дані. Проте для швидкого огляду використання пам'яті вашою програмою Аналізатор Продуктивності часто є найкращим інструментом.