OpenGL ES текстурная память - PullRequest
       0

OpenGL ES текстурная память

2 голосов
/ 11 января 2011

Я пытаюсь оптимизировать потребление текстурной памяти в своем родном приложении для Android. У меня есть два счетчика: первый - мой, который увеличивается каждый раз при вызове TexImage:

g_cbTextureMemory += ImageLineBytes(Format, width) * height;

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

Второй из системы:

adb shell dumpsys meminfo my.app.name

Это дает что-то вроде этого:

    ** MEMINFO in pid 3269 [my.app.name] **
                    native   dalvik    other    total
            size:    39320[*]  6663      N/A    45983
       allocated:    21453     3945      N/A    25398
            free:       34     2718      N/A     2752
           (Pss):     6281     3078    40643    50002
  (shared dirty):     2240     4968    12108    19316
    (priv dirty):     6232     2684    17948    26864

После этого я делаю следующее: я заменяю все текстуры на 1x1 (отправляя фиктивное изображение 1x1 в glTexImage). Я вижу, что meminfo дает другой результат, и ячейка разницы [*] изменилась на 22Mb. Но мой счетчик показывает, что у меня 25Mb текстур, поэтому я ожидаю 25Mb.

Так где в дампе текстура памяти потребляется скрытно? Для ясности, для дампов текстур 1х1:

    ** MEMINFO in pid 3269 [my.app.name] **
                    native   dalvik    other    total
            size:    16892     5575      N/A    22467
       allocated:    13211     3574      N/A    16785
            free:      208     2001      N/A     2209
           (Pss):     6273     3122    17016    26411
  (shared dirty):     2252     5032    10756    18040
   (priv dirty):      6224     2588     5848    14660

Почему я не получил 25Mb? Является ли статистическая ошибка? Включает ли родная куча текстурную память (кажется, что так и есть)? Или, может быть, для некоторых форматов Android имеют внутренние форматы, отличные от тех, которые я отправляю? Например, R8G8B8 трансформируется во что-то более оптимальное (кажется, что это не так)? Может все нормально, и есть рациональное объяснение?

1 Ответ

2 голосов
/ 21 апреля 2011

Здесь есть несколько проблем.

Я предполагаю, что вы получите разницу в 22 МБ, сравнивая строку размера. Это общее количество памяти, запрошенное процессом. Этому значению могут способствовать два фактора.

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

Вторым фактором, который может повлиять на размер процесса, является то, что библиотека C (или Dalvik VM, или любое управление памятью в пользовательском пространстве) будет запрашивать память большими порциями, чем запрашивает приложение. Это сделано из соображений производительности, поскольку частое выделение / освобождение небольших буферов может быть выполнено без выполнения системного вызова. Следовательно, фактическая память, используемая процессом, не будет хорошо указана параметром size выше - она ​​может служить только в качестве грубой верхней границы. Фактически, строка «распределенная» будет лучшим указанием на максимальный объем памяти, используемый приложением, поскольку она отслеживает страницы, на которые фактически ссылаются.

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

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...