Я пытаюсь теперь долгое время оптимизировать framerate своей игры без реальных успехов. Я работаю на новейшем iPhone SDK и имею iPhone 3G 3.1.2 устройства.
Я вызываю приблизительно 150 drawcalls, представляя приблизительно 1 900 Треугольников всего (все объекты текстурируются с помощью двух texturelayers и мультитекстурирования. большинство структур прибывает из того же textureAtlasTexture, сохраненного в pvrtc 2 бит/пкс сжатая структура). Это представляет по моему телефону на уровне приблизительно 30 кадр/с, который, кажется мне является слишком низким только для 1 900 треугольников.
Я попробовал много вещей оптимизировать производительность, включая пакетную обработку вместе объектов, преобразование вершин на ЦП и рендеринге их в единственном drawcall. этот yelds 8 drawcalls (как отклонено к 150 drawcalls), но производительность о том же (спад кадр/с приблизительно до 26 футов в секунду)
Я использую 32-байтовые вершины, сохраненные в чередованном массиве (12-байтовое положение, 12 байтов normals, 8-байтовый UV). Я представляю triangleLists, и вершины заказаны в порядке TriStrip.
Я сделал некоторое профилирование, но я действительно не знаю как к interprete оно.
выборка инструментов с помощью Инструментов и Выбирая yelds этот результат: http://neo.cycovery.com/instruments_sampling.gif говоря мне, что много времени проведено в "mach_msg_trap". Я погуглил для него, и кажется, что эта функция вызвана для ожидания некоторых других вещей. Но ожидайте какой??
инструментальные-openGL инструменты с openGL модулем yelds этот результат: http://neo.cycovery.com/intstruments_openglES_debug.gif, но здесь у меня нет действительно идеи, что те числа говорят мне
профилирование акулы: профилирование с акулой не сказало мне очень также: http://neo.cycovery.com/shark_profile_release.gif наибольшее число составляет 10%, потраченных DrawTriangles - и целый отдых, потрачен в функциях очень небольшого процента
Кто-либо может сказать мне, что еще я мог сделать, чтобы выяснить узкое место и мог помочь мне к interprete те профильная информация?
Большое спасибо!
Я, к сожалению, не хорошо разбираюсь в OpenGL, но вот некоторые вещи выделяются у меня из трех результатов:
1) от прибора выборки, у вас может быть какой-то фоновый веб-соединение?
2) Оказанные проценты использования кажутся низкими для меня (хотя я не знаю, как их улучшить).
3) Хотя 10% кажется низким, что кажется хорошей точкой атаки - однако это почти одинаково подозревает, что в мемкпите было столько времени. Также ValidateState - это рода лировная сумма и может удерживать вас назад.
Мудрый инструмент, я думаю, вы используете правильные инструменты для изучения производительности, вам просто нужно больше думать о том, что означают для вашего приложения.
Вероятно, вы связаны с процессором. Статистика использования тилера/рендера в инструменте OpenGL ES показывает, что рабочий цикл GPU составляет 20-30% при рендеринге на скорости 20-30 к/с, что говорит о том, что GPU может работать на скорости 60 к/с, если его подавать достаточно быстро. Похоже, что есть несколько вещей, которые можно сделать, чтобы получить больше информации от Инструментов и Шарка о том, к чему стремиться:
По умолчанию Sampler показывает каждый пример из каждого потока, что означает, что в большинстве случаев, созданные системными фреймворками вспомогательные потоки будут доминировать над вашим взглядом. Чтобы получить лучшее представление о том, что процессор на самом деле делает, убедитесь, что отображается Detail View (третья кнопка слева в левом нижнем углу) и измените Sample Perspective на Running Sample Times, чтобы исключить сэмплы, в которых поток простаивает/заблокирован.
Я не вижу никаких сэмплов в трассе Shark trace из самого вашего приложения. Возможно, это связано с тем, что ваш код достаточно быстр, чтобы не появляться нигде в списке горячих функций, но это также может быть связано с тем, что Shark не может найти символы для вашего приложения. Возможно, вам понадобится настроить пути поиска в его предпочтениях или вручную направить Shark на бинарный файл вашего приложения. Кроме того, Shark по умолчанию показывает список функций, упорядоченных по тому, сколько процессорного времени в них затрачено. Может быть полезно изменить вид на что-то более похожее на обычное дерево вызовов, чтобы вы могли визуализировать, как ваш общий цикл рендеринга тратит свое время. Для этого измените опцию "Вид" в правом нижнем углу на "Дерево (сверху вниз)". (Если вы также не видите здесь название вашего приложения или функций, то Shark определенно не хватает ваших символов)
.Без полного исходного текста трудно сказать, что именно происходит. Трассировка Instruments показывает 20% Render Utilization, что немного мало. Это, вероятно, означает, что вы ограничены процессором. Однако, если бы это было так, я бы ожидал увидеть больше точек выборки для конкретного приложения в вашей первой трассировке.
Мой совет - создать свой собственный класс синхронизации. Что-то вроде этого (c++):
#include <sys/time.h>
class Timer
{
public:
Timer()
{
gettimeofday(&m_time, NULL);
}
void Reset()
{
gettimeofday(&m_time, NULL);
}
// returns time since construction or Reset in microseconds.
unsigned long GetTime() const
{
timeval now;
gettimeofday(&now, NULL);
unsigned long micros = (now.tv_sec-m_time.tv_sec)*1000000+
(now.tv_usec-m_time.tv_usec);
return micros;
}
protected:
timeval m_time;
};
Засекайте время в своих секциях кода, чтобы точно знать, на что тратится время.
Также еще одно быстрое решение - отключить набор инструкций Thumb. Это может повысить производительность вычислений с плавающей запятой на 20% или более, за счет увеличения размера исполняемого файла.
Если вы используете glFlush или glFinish, удалите их все.