Как интегрировать профилировщик наименее инвазивным способом?

Как интегрировать профилировщик наименее инвазивным способом?
Как интегрировать профилировщик наименее инвазивным способом? - tbep @ Unsplash

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

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

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

Поэтому я пытаюсь придумать наименее инвазивный способ внедрения разметки Трейси и наиболее гибкий способ.

Например, это отмеченная зона:

ModuleStorage::ModuleStorage()
{
    ZoneScoped
    NECore::ModuleData module_data = {};
    module_data.renderer_so_path = NE_RENDERER_PATH;
    module_data.peripheral_so_path = NE_PERIPHERAL_PATH;

    LoadRenderingModule(module_data);
    LoadPeripheralModule(module_data);

    window = InitWindow();
    vk_meta_data = InitializeRendering(window->GetGLFWWindow());

    LogLoadedState(module_data, vk_meta_data);
}

Я могу поставить ее рядом со скобкой, чтобы было понятно, что это не логически часть функции:

ModuleStorage::ModuleStorage()
{ ZoneScoped
...

Я мог бы добавить комментарий после каждой пометки (но это утомительно).

Я могу сделать скрипт, который удаляет их и считывает по требованию (но это кажется плохой идеей).

Некоторые вещи не имеют удовлетворительного решения

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

Чтобы отключить/включить трассировку, не редактируйте все функции. Вместо этого используйте функции, которые язык уже предоставляет вам, в частности препроцессор. Например, #define макросы трассировки как пустые, если вы хотите сборку без трассировки (что, кстати, уже является значением по умолчанию, если вы компилируете без TRACY_ENABLE). Или используйте встроенную поддержку фильтрации Трейси (логический параметр active макроса ZoneNamed()).

Вы предлагаете добавить скрипт для добавления/удаления необходимых маркеров для трассировки, но я настоятельно не рекомендую этого делать. Такие сценарии трудно написать достаточно правильно, потому что C++ — очень сложный язык. Скрипт легко мог что-то сломать. Если сценарии основаны на специальных соглашениях о форматировании, эти соглашения могут не выдержать проход от автоматического форматирования, такого как clang-format. Версии с трассировкой и без нее будут иметь другую кодовую базу, что делает ее, например. трудно сравнивать номера строк. Вместо этого настоятельно рекомендуется сохранять как можно более унифицированную кодовую базу и вводить различные варианты кода только в процессе сборки, в частности, путем осторожного использования ifdef.


LetsCodeIt, 19 декабря 2022 г., 03:00