Профилирование игры WebGL

Чтобы заставить быстрее работать игры HTML5, вы должны сначала определить (узкие) места в производительности, и это может быть трудно. Оценка кадров в секунду (FPS), но чтобы увидеть полную картину, вы должны понять нюансы в работе Chrome и прочитать статью Основы WebGL

Инструмент about:tracing даёт понимание того, как нужно избежать поспешных обходных путей направленных на улучшение производительности, и выполнить правильные действия. Вы сэкономите много времени и энергии, получите более ясную картину того, как Chrome обрабатывает каждый кадр, и использует эту информацию для оптимизации игры WebGL.

about:tracing

В Chrome существует инструмент about:tracing  и покажет вам детальную деятельность в окне Chrome во всех направлениях. Многие функции в Chrome для отслеживания с аппаратным ускорением, так что вы можете использовать about:tracing для отслеживания производительности. (См. далее в разделе о ручном инструменте JS)

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

Чтобы увидеть трассировку простого типа about:tracing в Omnibox Chrome (в адресной строке).

Chrome Omnibox

about:tracing в Omnibox Chrome

С средством трассировки, вы можете начать запись, запустить игру в течение нескольких секунд, а затем просматривать данные трассировки. Пример того, как данные могут выглядеть:

Простое отслеживание результатов

Данные трассировки Omnibox Chrome

Отслеживание результатов

Давайте поговорим о том, как в этих данных разобраться.

Каждая строка представляет собой процесс создания профиля, левая-правая полоса указывает время, а каждое цветное окно вызов функции инструментов. Есть строки для целого ряда различных видов ресурсов. Те, которые наиболее интересны для профилирования игры называются CrGpuMain, и показывает работу графического процессора (GPU) на полосе CrRendererMain. Каждый отрезок CrRendererMain содержит линий для каждой открытой вкладки (в том числе открытого about:tracing).

При чтении данных трассировки, вашей первой задачей является определение, какая строка CrRendererMain относится к игре.

Простое отслеживание результатов выделены

Простое отслеживание результатов

В этом примере две полосы: 2216 и 6516. К сожалению, в настоящее время не полированный способ выбор приложении, за исключением поиска строки, которая делает много периодического обновления. В данном примере это выглядит как 6516 работает основной цикл от частоты обновления. Если закрыть все вкладки перед началом следа, узнав правильный CrRendererMain будет легче. Но все еще ​​может быть строки CrRendererMain для других процессов, кроме игры.

Поиск нужного кадра

После того как вы расположили нужные строки в инструменте отслеживания для вашей игры, следующим шагом является определение основного цикла. Основной цикл выглядит как повторяющийся узор в отслеживании данных. Вы можете перемещаться по отслеживанию данных с помощью клавиш W, A, S, D.  Клавиша D для перемещения влево или вправо (вперед и назад во времени) и W и S, чтобы увеличивать и уменьшать на данные. Можно ожидать, что ваш основной цикл образца, будет повторяется каждые 16 миллисекунд, если игра работает с чистотой 60 Гц.

Похоже, что три кадра исполнения

Три кадра исполнения

После того как вы расположили сердцебиение в вашей игре, вы можете углубиться в том, что именно ваш код делает в каждом кадре. Используйте W, A, S, D для увеличения пока вы не можете прочитать текст в функции окна.

Глубоко в исполнении кадров

Исполнение кадров

Эта коллекция строк показывает ряд вызовов функций, при каждом вызове представлены цветные окна. Каждая функция вызывает окно над ним, так что в этом случае, вы можете видеть, что MessageLoop :: RunTask называется RenderWidget :: OnSwapBuffersComplete, который в свою очередь, называют RenderWidget :: DoDeferredUpdate, и так далее.

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

Добавление тегов Trance

К счастью, это удобный способ для добавления кодf для создания данных трассировки: console.time и console.timeEnd .



console.time("update");  
update();  
console.timeEnd("update");  
console.time("render");  
update();  
console.timeEnd("render");


Приведенный выше код создаёт новые ящики в отслеживании названия с указанными тегами, так что если вы повторно запустите приложение, вы увидите «update» и «render» ячейки, которые показывают время, прошедшее между началом и концом вызова для каждого тега.

Тэги, добавленные вручную

Тэги, добавленные вручную

С помощью этого, вы можете создать отслеживания данных для отслеживания горячих точек в вашем коде.

GPU или CPU?

С аппаратным ускорением графики, один из самых важных вопросов, которые вы можете задать во время профилирования: является ли этот код связанным с GPU или CPU? С каждого кадра вы будете делать некоторые работы по оказанию GPU и некоторую логику процессора, для того, чтобы понять, что тормозит игру вы должны увидеть, как работа распределяется между двумя ресурсами.

Во-первых, найти линию на отслеживание представление с названием CrGPUMain, которое указывает, занят ли GPU в конкретный момент времени.

GPU и GPU в конкретный момент времени

Отслеживание GPU в конкретный момент времени

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

Отслеживание действительно становится полезным, когда у вас есть игра, которая работает медленно, и вы не уверены, каком ресурсе вы полностью исчерпали свободные разъемы. Глядя на то, как линии GPU и CPU является ключом к отладке. Возьмём тот же пример, как и раньше, но добавим немного дополнительной работы в обновлении цикла.



console.time("update");
  doExtraWork();
  update(Math.min(50, now - time));
  console.timeEnd("update");

  console.time("render");
  render();
  console.timeEnd("render");


Теперь вы увидите след, который выглядит следующим образом:

Каждый кадр занимает около 50 мс (частота кадров 20 Гц)

Каждый кадр занимает около 50 мс (частота кадров 20 Гц)

Что это след нам расскажет? Мы видим, что изображен фрейм от о 2270ms до 2320ms Это означает, что каждый кадр занимает около 50 мс (частота кадров 20 Гц). Вы можете увидеть осколки цветных строк, функция визуализации рядом обновление окна, но рамка полностью доминирует обновляя себя.

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

А когда код шейдера медленный и GPU перегружен? Что делать, если мы удаляем ненужную работу с процессором, а вместо этого добавить работу в коде фрагмент шейдеров. Вот напрасные дорогие фрагменты шейдера:



#ifdef GL_ES
  precision highp float;
  #endif
  void main(void) {
  for(int i=0; i<9999; i++) {
  gl_FragColor = vec4(1.0, 0, 0, 1.0);
  }
}


GPU и процессор следов при использовании медленного GPU код

Следы GPU и CPU при использовании медленного кода GPU

Опять же, обратите внимание на длительность кадра. Здесь повторяющийся узор идет от о 2750ms до 2950ms, продолжительностью 200 мс (частота кадров около 5 Гц). Линия CrRendererMain почти полностью пустая и означает, что CPU простаивает большую часть времени, в то время как GPU перегружен. Это верный признак того, что ваши шейдеры являются слишком тяжелыми.

Если у вас не было прозрачности, что именно является причиной низкой частоты кадров, вы можете наблюдать за 5 Гц обновления и желание пойти в игровой код и начать пытаться оптимизировать или удалить игровую логику. В этом случае, что бы сделать абсолютно ничего хорошего, потому что логики в игровой цикл не то, что съедает время. На самом деле, что это след указывает, что делать больше CPU работают каждый кадр был бы по существу «free» в том, что процессор стоит без дела, тем самым, он больше работать не будет и нужно влиять на сколько кадров.

Примеры игры HTML5

Теперь давайте посмотрим на вид данных при отслеживании реальной игры. Одна из замечательных особенностей игры построена с открытыми веб-технологиями является то, что вы можете видеть, что происходит в вашей любимой игре. Если вы хотите проверить средства профилирования Вы можете выбрать свой любимый WebGL название из магазина Chrome Web и профиль его about:tracing. Ниже пример, след взят из прекрасной Мини игры WebGL Racer.

Отслеживание реальной игры

Отслеживание реальной игры

Похоже, что каждый кадр занимает около 20 мс, что означает, что частота кадров составляет около 50 FPS. Вы можете видеть, что работа балансируется между CPU и GPU, но ресурсы CPU наиболее востребованы. Если вы хотите увидеть, каково это для профилирования реальные примеры WebGL игры пытаются играть с некоторыми веб-магазин Chrome названия построены с WebGL в том числе:

Заключение

Если вы хотите, чтобы ваша игра работала на 60 Гц, то для каждого кадра, все операции должны вписываться в 16мс CPU и GPU 16мс времени. У вас есть два средства, которые могут быть использованы параллельно, и вы можете перемещать между ними работу для достижения максимальной производительности.

Что дальше?

Помимо GPU, вы также можете отслеживать другие части выполнения Chrome. Chrome Canary, ранние версии Chrome, является инструментальной в след IO, IndexedDB и ряд других интерфейсов. Вы должны прочитать  эту статью  для более глубокого понимания текущего состояния трассировки событий.

Если вы веб-разработчик игры, посмотрите видео ниже. Это презентация игры Google’s Game Developer Advocate команда GDC 2012 об оптимизации производительности игры Chrome:

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML -теги и атрибуты: <a href= http://pixelcom.crimea.ua/"" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>