Идентификация и решение проблем производительности

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

Удостоверяясь Вы используете функции правильно

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

Идентификация проблемных областей в приложении

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

Собрать трассировку для единственного кадра:

  1. Запуск или присоединение к приложению интереса.

  2. Откройте окно Statistics.

  3. Перейдите в приложении к области, где Вы подозреваете проблему.

  4. Установите точку останова на функции CGLFlushDrawable. При использовании однобуферного контекста рендеринга Вы, возможно, также должны были бы установить точку останова на функции glFlush.

  5. Когда Ваши паузы приложения, нажмите Clear в окне Statistics.

  6. Нажмите Continue в окне Breakpoints. Когда Ваши паузы приложения, удостоверьтесь, что это представило кадр полностью. В противном случае Ваш код, вероятно, вызывает больше чем одну работу сброса на кадр.

    Затем проверьте на следующее в окне Statistics:

    • Управление состоянием. Проверьте, чтобы видеть, вызываете ли Вы glPopAttrib вызовы. Если возможный необходимо вместо этого отследить собственное состояние. Это не хорошая идея установить состояние на на основание кадра. Лучше консолидировать изменения состояния и устанавливать их вне кадра.

    • Вызовы, занимающие значительно больше времени, чем другие.

    • Любые вызовы OpenGL, перечисленные в Проверке Вас Функции Использования Правильно.

  7. Нажмите кнопку Continue в окне Breakpoints для возобновления выполнения приложения.

Проверка оптимальные типы данных и форматы

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

Идеально, Вы захотите использовать:

GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV

Это - самый быстрый тип данных и комбинация формата. Если это не быстро, у Вас может быть проблема с Вашим драйвером.

Если это не возможно, можно часто получать приемлемую производительность от следующего. Просто удостоверьтесь, что протестировали эти комбинации на последовательно по каждому устройству основание:

GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV

GL_YCBR_422_APPLE, GL_UNSIGNED_SHORT_8_8_REV_APPLE

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

  1. Выберите Collect Trace и Include Backtraces в окне OpenGL Profiler.

  2. Установите точку останова, где загружаются Ваши данные.

  3. Когда Ваше приложение повредится, нажмите Call Stack в окне Trace.

Управление данными трассировки

Объем данных, сгенерированный при сборе трассировки, может быть подавляющим. Большую часть времени Вы соберете трассировку только для одного кадра, который является достаточно обычно для разыскивания наиболее распространенных проблем. (См. Проблемные области Идентификации в Своем Приложении.), Если действительно необходимо собрать больше, чем кадр данных, можно создать пользовательский сценарий оболочки, воздействующий на данные трассировки так, чтобы можно было получить его в более управляемое состояние. Когда Вы захотите применить сценарий, нажмите кнопку Filter в окне Trace. Профилировщик OpenGL предоставляет данные трассировки, как введено (stdin) к Вашему сценарию и записям результаты Ваших сценариев вызывает к stdout.

Если вызов получения является медленным, и Вы подозреваете, что программа построения теней является причиной, Вы, возможно, должны собрать больше, чем кадр данных. Можно тогда использовать сценарий для срезания данных к подозрительным вызовам. Перечисление 3-1 показывает очень простой сценарий, что виды вызывают ко времени вызова функции с самыми медленными вызовами в последний раз. Ваш сценарий должен был бы быть настроен так, чтобы он выполнил операции, подходящие для проблемы, которую Вы пытаетесь изолировать. После использования сценария для идентификации подозрительных вызовов, можно использовать номер строки вывода для прослеживания туда, где вызов фактически имел место.

Перечисление 3-1  сценарий оболочки для нахождения самых медленных вызовов в трассировке

#!/bin/tcsh -f
awk '{ print $3" "$0 }' | sort -n

Создать сценарий:

  1. Откройте приложение, такое как XCode, позволяющий Вам создать файл простого текста.

  2. Введите надлежащие команды сценария с помощью любого языка сценариев, принимающего ввод от stdin.

  3. Сохраните сценарий с a .filter расширение.

    Можно сохранить его к любому расположению, которое Вы хотели бы.

  4. Для первого сценария, который Вы создаете, выберите его в Средстве поиска и выберите File> Get Info.

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

Отфильтровать данные трассировки:

  1. Откройте окно Trace.

  2. Нажмите Browse, перейдите к сценарию, Вы хотите использовать, и выбрать его.

    Можно изменить существующий сценарий путем щелчка по Open.

  3. Нажмите Filter, затем обеспечьте имя для выходного файла.

Проверка ошибки приложения, конфликты потока и нейтрализации программного обеспечения

Можно быстро проверить на ошибки в приложении путем установки одной или более точек прерывания при ошибке. Использовать Профилировщика OpenGL для проверки на ошибки приложения:

  1. Выберите View> Breakpoints.

  2. Выберите один или больше этих опций:

    • Повреждение на ошибке. Ваши паузы приложения, когда это встречается с любым типом ошибки.

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

    • Повреждение на конфликте потока. Если приложение многопоточно, можно выбрать это.

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

  3. Если Вы уже не сделали так, запускаете или присоединяете свое приложение.

  4. Контролируйте окно Breakpoints для ошибок.

Оценка эффекта многопоточного механизма OpenGL

В OS X v10.5 и позже, платформа OpenGL может разгрузить обработку на отдельный поток, работающий на различном ядре CPU. Вы используете CGLEnable функция для включения многопоточного выполнения программно с помощью этого кода:

#include <OpenGL/OpenGL.h>
 
CGLError err = 0;
CGLContextObj ctx = CGLGetCurrentContext();
 
// Enable the multi-threading
err =  CGLEnable( ctx, kCGLCEMPEngine);
 
if (err != kCGLNoError )
{
     // Multi-threaded execution is possibly not available
     // Insert your code to take appropriate action
}

Для получения дополнительной информации посмотрите Техническое примечание TN2085: Включение многопоточного выполнения платформы OpenGL.

После включения многопоточности некоторые приложения видят значительное увеличение производительности OpenGL; другие не могли бы. В целом многопоточный механизм OpenGL является хорошей опцией для приложений, которые являются связанным CPU.

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

  1. Запуск или присоединение к приложению интереса.

  2. В основном окне OpenGL Profiler проверьте частоту кадров в точке в Вашем приложении, которое повторимо. Вы проверите эту ту же точку позже.

  3. Выберите Views> Breakpoints.

  4. Удостоверьтесь, что многопоточная опция управления установлена в «Управление приложениями».

  5. В основном окне OpenGL Profiler проверьте частоту кадров.

  6. Установите точку останова на функции.

    Несмотря на то, что можно выбрать любую функцию, обычно Вы установили точку останова на CGLFlushDrawable для контекста рендеринга с двойной буферизацией или glFlush для однобуферного контекста рендеринга.

  7. Когда Ваши паузы приложения, выберите опцию «Force off» для многопоточного управления.

  8. Нажмите Continue для возобновления выполнения приложения.

  9. В основном окне OpenGL Profiler проверьте частоту кадров.

    Сравните эту частоту кадров с уровнем, который Вы наблюдали при использовании многопоточного механизма OpenGL.

Контроль использования GPU

Приложения, которые не могут использовать GPU по некоторым причинам (такой как видеокарта не поддерживает некоторые расширения OpenGL, которые Ваш код использует) используют средство рендеринга программного обеспечения в качестве нейтрализации. Если Вы замечаете понижение производительности Вашего приложения, можно хотеть проверить, использует ли приложение GPU, как Вы ожидаете.

Запускаясь в OS X v10.5, можно установить приложение для повреждения каждый раз, когда это использует средство рендеринга программного обеспечения в качестве нейтрализации. (См. Проверку Ошибки приложения, Конфликты Потока и Нейтрализации программного обеспечения.) До OS X v10.5, можно контролировать использование GPU приложения каждый раз, когда паузы приложения в точке останова. Лучшие точки останова для проверки:

Когда Ваши паузы приложения в этих точках останова, проверьте значения kCGLCPGPUFragmentProcessing и kCGLCPGPUVertexProcessing показанный в области Call Stack окна Breakpoints. Значение GL_TRUE указывает, что Ваше приложение использует GPU для процесса, связанного с константой.

Используя изменение размеров окна для диагностирования производительности

Если Ваше приложение представляет к окну, можно часто идентифицировать причину проблем производительности путем изменения размеров окна. В то время как Ваш рендеринг приложения к окну, измените размеры его. После уменьшения окна если время выполнения значительно быстрее, то проблема могла бы быть связана с низким VRAM. Если время выполнения быстрее пропорциональный размеру окна, то Ваше приложение является связанным фрагментом. Если время выполнения является тем же, то Ваше приложение или является вершиной, привязал GPU или связанный CPU.

Идентификация несопоставленных вызовов

Много вызовов в OpenGL используются в качестве наборов, таких как:

Можно проверить # столбца Calls в окне Statistics, чтобы удостовериться, что они (и подобные наборы) являются всегда соответствующими в приложении. Например, если Вы находите 5 glBegin вызовы, но только 3 glEnd вызовите, необходимо изменить код так, чтобы у Вас было то же число каждого. Несопоставленные вызовы обычно являются признаком ненужного кода и всегда указывают неточный код. Наборы вызова должны всегда соответствовать в кадре.