Нативный плагин API для профилирования
Вы можете использовать низкоуровневый профилирующий модуль API для расширения до Profiler и сбора данных о производительности кода основного модуля или подготовки данных профилирования для отправки в сторонние инструменты профилирования, такие как Razor (PS4), PIX (Xbox, Windows), Chrome Tracing, ETW, ITT, Vtune или Telemetry.
Низкоуровневый собственный плагин Profiler APIs предоставляет следующие интерфейсы для связи между Unity Profiler и внешними инструментами:
- IUnityProfiler: используйте этот интерфейс, чтобы добавлять события инструментирования в Unity Profiler из кода нативного плагина.
- IUnityProfilerCallbacks: используйте этот интерфейс, чтобы перехватывать события Unity Profiler и сохранять или перенаправлять их в другие инструменты.
IUnityProfiler API ссылка
Используйте IUnityProfiler плагин API для добавления инструментов к вашим собственным плагинам. Плагин API представлен IUnityProfiler интерфейс, объявленный в IUnityProfiler.h заголовок, расположенный в папка PluginAPI.
| Метод | Описание |
|---|---|
CreateMarker |
Создает маркер Profiler, который представляет именованную область приборов, которую можно использовать для создания образцов приборов. |
SetMarkerMetadataName |
Указывает имена пользовательских параметров, которые могут быть переданы вместе с образцом прибора для маркера Profiler. |
BeginSample |
Начинается инструментальная часть кода, названного в честь маркера Profiler. |
EndSample |
Завершает раздел инструментов. |
EmitEvent |
Выпускает общие события с метаданными. |
IsEnabled |
Возвращает 1, если Profiler захватывает данные. |
IsAvailable |
Возвращает 1 для Редакторов или Разработчиков, где Profiler доступен, и 0 для Релизов. |
RegisterThread |
Регистрирует текущий поток под указанным именем. |
UnregisterThread |
Отрегистрирует текущий поток из Profiler. |
Пример IUnityProfiler
В следующем примере создаются события Profiler, которые могут отображаться в окне Profiler:
#include <IUnityInterface.h>
#include <IUnityProfiler.h>
static IUnityProfiler* s_UnityProfiler = NULL;
static const UnityProfilerMarkerDesc* s_MyPluginMarker = NULL;
static bool s_IsDevelopmentBuild = false;
static void MyPluginWorkMethod()
{
if (s_IsDevelopmentBuild)
s_UnityProfiler->BeginSample(s_MyPluginMarker);
// Code I want to see in Unity Profiler as "MyPluginMethod".
// ...
if (s_IsDevelopmentBuild)
s_UnityProfiler->EndSample(s_MyPluginMarker);
}
extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API UnityPluginLoad(IUnityInterfaces* unityInterfaces)
{
s_UnityProfiler = unityInterfaces->Get<IUnityProfiler>();
if (s_UnityProfiler == NULL)
return;
s_IsDevelopmentBuild = s_UnityProfiler->IsAvailable() != 0;
s_UnityProfiler->CreateMarker(&s_MyPluginMarker, "MyPluginMethod", kUnityProfilerCategoryOther, kUnityProfilerMarkerFlagDefault, 0);
}
extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API UnityPluginUnload()
{
s_UnityProfiler = NULL;
}
IUnityProfilerCallbacks API обратные вызова
API нативных плагинов профайлера связывает подсистемы Unity со сторонними API профилирования, позволяя профилировать приложение Unity внешним инструментом. IUnityProfilerCallbacks заголовок показывает API, который Unity хранит в <UnityInstallPath>\Editor\Data\PluginAPI папку вашей установки Unity. (На macOS щелкните правой кнопкой мыши приложение Unity и выберите Показать содержимое пакетаЗаголовок находится в Contents\PluginAPI).
Следующие функции Unity Profiler помогают записывать данные измерений, чтобы вы могли анализировать производительность вашего приложения:
| Profiler особенность | Описание |
|---|---|
| Категории | Unity группирует данные профиля по категориям (например, Рендрирование, Сценарии и Animation) и назначает каждой категории цвет. Цветные категории помогают визуально различать типы данных в окне Profiler. Основной плагин Profiler API извлекает эти цвета, чтобы вы могли использовать их во внешнем инструменте профилирования. |
| Флаги использования | Флаги использования действуют как фильтр, уменьшающий объем данных, которые Unity отправляет во внешний инструмент профилирования. Флаги использования можно использовать для удаления ненужной информации из данных профилирования до того, как Unity отправит их во внешний инструмент. Profiler применяет следующие флаги использования к маркерам событий, чтобы можно было фильтровать данные: Флаги доступности Флаг, указывающий, доступен ли маркер в Unity Editor, проигрывателе разработки или проигрывателе релиза. Уровни подробности Зависит от типа задачи, которую вы решаете в редакторе, и от нужного уровня детализации сведений (например, внутренний, отладочный или пользовательский). |
| Фрейм событий | Для выполнения анализа времени кадра во внешнем инструменте профилирования можно использовать собственный плагин Profiler API. |
| Профилирование резьбы | Unity выполняет значительное количество работы на потоках (например, на главном потоке, потоке отображения и потоке рабочей системы задания). Вы можете использовать плагин Profiler API для включения профилирования на любом потоке. |
Чтобы использовать данные инструментария, которые Unity Profiler генерирует во внешнем профилере, вы можете использовать следующий минимальный набор обратных вызовов в коде плагина C/C++, который интегрирует сторонний профилер:
| Обратный вызов | Функция |
|---|---|
RegisterCreateCategoryCallback |
Зарегистрирует обратный вызов IUnityProfilerCreateCategoryCallback для получения имени и цвета категории Profiler каждый раз, когда Unity создает категорию. |
RegisterCreateMarkerCallback |
Регистрирует обратный вызов IUnityProfilerCreateMarkerCallback, который вызывается всякий раз, когда Unity создает метку. Используйте его для получения имени, категории Profiler и флагов использования метки. Параметр const UnityProfilerMarkerDesc* markerDesc функции обратного вызова представляет собой постоянный указатель на описание метки, который можно использовать для фильтрации меток в RegisterMarkerEventCallback. |
RegisterMarkerEventCallback |
Регистрирует обратный вызов IUnityProfilerMarkerEventCallback, который Unity вызывает при возникновении событий single-shot, scoped, выделения памяти или сбора мусора. Затем вы можете использовать этот обратный вызов для вызова соответствующих функций во внешнем инструменте профилирования. Примечание: Unity представляет события выделения памяти с меткой GC.Alloc, а события сбора мусора с метками GC.Collect. |
RegisterFrameCallback |
Инкапсулирует образцы в логические кадры, чтобы внешние инструменты профилирования, не использующие кадры, могли использовать эти образцы. Также регистрирует обратный вызов, что Unity Profiler запускается, когда Unity запускает следующий логический CPU кадр. |
RegisterCreateThreadCallback |
Регистрирует обратный вызов, который получает внутреннее имя потока каждый раз, когда Unity регистрирует поток для профилирования. |
Пример IUnityProfilerCallbacks
В этом примере показано, как передать события Unity Profiler другому профилеру, имеющему семантику push/pop. Он предоставляет две функции:
void MyProfilerPushMarker(const char* name): отправляет именованный маркер.void MyProfilerPopMarker(): всплывает маркировка приборов.
В следующем примере представлена минимальная реализация, необходимая для передачи событий начала и окончания измерений от Unity Profiler к внешнему профилирующему устройству:
#include <IUnityInterface.h>
#include <IUnityProfilerCallbacks.h>
static IUnityProfilerCallbacks* s_UnityProfilerCallbacks = NULL;
static void UNITY_INTERFACE_API MyProfilerEventCallback(const UnityProfilerMarkerDesc* markerDesc, UnityProfilerMarkerEventType eventType, unsigned short eventDataCount, const UnityProfilerMarkerData* eventData, void* userData)
{
switch (eventType)
{
case kUnityProfilerMarkerEventTypeBegin:
{
MyProfilerPushMarker(markerDesc->name);
break;
}
case kUnityProfilerMarkerEventTypeEnd:
{
MyProfilerPopMarker();
break;
}
}
}
static void UNITY_INTERFACE_API MyProfilerCreateMarkerCallback(const UnityProfilerMarkerDesc* markerDesc, void* userData)
{
s_UnityProfilerCallbacks->RegisterMarkerEventCallback(markerDesc, MyProfilerEventCallback, NULL);
}
extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API UnityPluginLoad(IUnityInterfaces* unityInterfaces)
{
s_UnityProfilerCallbacks = unityInterfaces->Get<IUnityProfilerCallbacks>();
s_UnityProfilerCallbacks->RegisterCreateMarkerCallback(&MyProfilerCreateMarkerCallback, NULL);
}
extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API UnityPluginUnload()
{
s_UnityProfilerCallbacks->UnregisterCreateMarkerCallback(&MyProfilerCreateMarkerCallback, NULL);
s_UnityProfilerCallbacks->UnregisterMarkerEventCallback(NULL, &MyProfilerEventCallback, NULL);
}
Примечание: Чтобы отменить регистрацию указанного обратного вызова со всех маркеров, запустите UnregisterEventCallback с первым параметром установленным на null.
Пример UnitySystracePlugin
Регистрировать и отменять регистрацию обратных вызовов маркеров можно динамически, раз в кадр. В следующем примере нагрузка на профилирование снижена за счёт включения и отключения обратных вызовов в зависимости от состояния стороннего профиля.
| static void UNITY_INTERFACE_API SystraceFrameCallback(void* userData)
{
bool isCapturing = ATrace_isEnabled();
if (isCapturing != s_isCapturing)
{
s_isCapturing = isCapturing;
if (isCapturing)
{
s_UnityProfilerCallbacks->
RegisterCreateMarkerCallback(SystraceCreateEventCallback, NULL);
}
else
{
s_UnityProfilerCallbacks->
UnregisterCreateMarkerCallback(SystraceCreateEventCallback, NULL);
s_UnityProfilerCallbacks->
UnregisterMarkerEventCallback(NULL, SystraceEventCallback, NULL);
}
}
}
Примечание: Чтобы отменить регистрацию указанного обратного вызова со всех маркеров, запустите UnregisterEventCallback с первым параметром установленным на null.
Специальные маркеры
Unity имеет следующие специальные маркеры, которые содержат полезные метаданные:
Profiler.DefaultMarkerGC.Alloc
Profiler.DefaultMarker
Profiler.DefaultMarker — это маркер, который Unity резервирует для событий Profiler.BeginSample и Profiler.EndSample.
В предыдущем примере kUnityProfilerMarkerEventTypeBegin eventType соответствует событию Profiler.BeginSample и имеет следующие данные:
- Int32: экземпляр
UnityEngine.ObjectID. Это 0, если объект не указан. - UInt16 array: UTF16 строка, переданная
Profiler.BeginSample. Размер в байтах. - UInt32: Индекс категории.
GC.Alloc
GC.Alloc — это маркер, соответствующий распределению сбора мусора. Он имеет следующие данные:
- Int64: Размер выделения.