Profiling
Practical guide to optimization for mobiles

Optimizaciones

Tal como en PCs, las plataformas móviles como iOS y Android tienen dispositivos de varios niveles de rendimiento. Usted puede de manera fácil encontrar un celular que sea 10x más poderoso para renderizar que otros teléfonos. Modo muy fácil de escalamiento:

  1. Asegúrese de que corra bien en una configuración de linea de base
  2. Utilice más vistosidad en configuraciones de alto rendimiento:
    • Resolución
    • Post-procesamiento
    • MSAA
    • Anisotropía
    • Shaders
    • Densidad Fx/partículas, prendido/apagado

Centrarse en las GPUs

El rendimiento gráfico está vinculado por el fillrate, complejidad de pixeles y geometría (conteo de vértices). Todos estos tres pueden ser reducidos si usted encuentra una manera de cull (desechar) más renderizadores. El Occlusion culling (Desecho de oclusión) puede ayudarlo aquí ya que Unity de manera automática desechará objetos afuera del frustum de vista.

En móviles usted está esencialmente vinculado al fillrate (fillrate = pixeles de la pantalla * complejidad del shader * overdraw), y sobre los shaders complejos es la causa más común de causar problemas. Por lo que utilice los shaders móviles que vienen con Unity o diseño su propio pero hágalas lo más simple posible. Si es posible, simplifique sus shaders de pixel al mover el código al vertex shader.

Si se reduce la Texture Quality (Calidad de Textura) en los Quality Settings hace que el juego corra más rápido, usted probablemente está limitado por el bando de ancha de memoria. Por lo que comprima texturas, utilice mipmaps, reduzca el tamaño de textura, etc.

LOD (Level of Detail (Nivel de Detalle)) - hace que los objetos sean más simples o los elimina completamente a medida que se muevan más lejos.

Buenas prácticas

Los GPUs Móviles tienen grandes restricciones acerca de qué tanto calor pueden producir, qué tanto poder pueden utilizar, y qué tan grande o ruidosos pueden ser. Por lo que comparado a las partes del escritor, los GPUs móviles tienen menos banda ancha, un rendimiento bajo ALU y un poder de texturazación. Las arquitecturas de los GPUs también están prendidas para utilizar tan poco bandaancha y pode como sea posible.

Unity es optimizado para OpenGL ES 2.0, utiliza GLSL ES (similar a HLSL) para un lenguaje de shading. Los shaders integrados a menudo son escritos en HLSL (también conocido como Cg). Esto se compila de manera cruzada a GLSL ES para plataformas móviles. Usted también puede escribir GLSL directamente si usted quiere, pero al hacer esto lo limita a plataformas OpenGL- parecidas (e.g. móvil + Mac) ya que actualmente no hay herramientas de traslación GLSL->HLSL. Cuando usted utilice los tipos float/half/fixed en HLSL, estos terminan como calificadores de precisión highp/mediump/lowp en GLSL ES.

Una lista de buenas prácticas:

  1. Mantiene el número de materiales tan bajo como sea posible. Esto hace que para Unity sea fácil batch cosas.
  2. Utilice atlases de Textura (grandes imágenes conteniendo una colección de sub-imágenes) en vez de un número de texturas individuales. Estas son más rápidas para cargar, tener unos cambios de estados menos, y son amigables al batching.
  3. Utilice Renderer.sharedMaterial en vez de Renderer.material si se está utilizando atlases de textura y materiales compartidos.
  4. Las luces de pixeles forward rendered son costosas.
    • Utilice light mapping en vez de una iluminación en tiempo real dónde sea posible.
    • Ajuste la cuenta de luces de pixeles en los ajustes de calidad. Esencialmente sola la luz direccional ser por pixel, todo lo demás - por vértices. Ciertamente esto depende en el juego.
  5. Experimente con el Modo Render de las luces en los Quality Settings (Ajustes de calidad) para obtener la prioridad correcta.
  6. Evite los cutout (prueba alpha) shaders al menso de que sean realmente necesarios.
  7. Mantenga el cubrimiento de pantalla Transparente (alpha blend) a un mínimo.
  8. Intente evitar situaciones dónde varias luces iluminen cualquier objeto dado.
  9. Intente reducir el número en general de pases de shader (Sombras, luces de pixel, reflexiones).
  10. El orden de renderizado es crítico. Generalmente:
    • Objetos completamente opacos mas o menos de al frente- para-atrás.
    • Objetos probados alpha mas o menos del Frete-para-atras.
    • skybox.
    • objetos mezclados alpha (de atrás para adelante si se necesita).
  11. El Procesamiento Post es costoso en móviles, utilice con cuidado.
  12. Partículas: reduzca el overdraw, utilice los shaders más simples posibles.
  13. Un buffer doble para Meshes modificados cada frame:
void Update (){
  // flip between meshes
  bufferMesh = on ? meshA : meshB;
  on = !on;
  bufferMesh.vertices = vertices; // modification to mesh
  meshFilter.sharedMesh = bufferMesh;
}

Optimizaciones del Shader

Revisar si usted está vinculado al fillrate es fácil: Su juego corre más rápido si aumenta la resolución de la pantalla? Si es así, usted está limitado por el fillrate.

Intente reducir la complejidad de los shaders mediante los siguientes métodos:

  • Evite los shaders alpha-testing; en vez utilice versiones alpha-blended.
  • Utilice simple, pero código shader optimizado (tal como Los shaders “móviles” que están con Unity).
  • Evite funciones de matemática costosas en código shader (pow, exp, log, cos ,sin, tan, etc). Considere utilizar texturas lookup pre-calculadas más bien.
  • Escoja el número del formato de precisión más bajo posible (float, half, fixedin Cg) para un mejor rendimiento.

Centra en CPUs

A menudo es el caso que los juegos están limitados por el GPU en el procesamiento de pixel. Por lo que terminan con un poder CPU sin utilizar, especialmente en CPUs móviles multi-core. Entonces a menudo es sensible realizar un pull de algún trabajo en el GPU y ponerlo en el CPU más bien (Unity hace todos esto): mesh skinning, btaching de objetos pequeños, actualizaciones de la geometría de las partículas.

Estos deberían ser utilizados con cuidado, no ciegamente. Si usted no está vinculado a los draw calls, entonces el batching en realidad es peor para el rendimiento, ya que hace que el culling sea menos eficiente y hace que más objetos sean afectados por las luces!

Buenas prácticas

  • FindObjectsOfType (y las propiedades getter de Unity en general) son muy lentas, entonces utilice con sensibilidad.
  • Configura la propiedad estática en objetos no movibles para permitir optimizaciones internas como un batching estático.
  • Gasta muchos de los ciclos de CPU para hacer occlusion culling y un ordenamiento mejor (para sacarle ventaja a Early Z-cull).

Física

La física puede ser pesada para el CPU. Puede ser perfilada vía el perfilador del Editor. Si la física parece que toma mucho del tiempo de CPU:

  • Ajuste Time.fixedDeltaTime (en los Project settings (ajustes del proyecto) -> Time) a lo más alto posible que usted pueda. Si su juego está corriendo lento, usted probablemente necesita menos fixed updates que juegos con acciones rápidas. Los juegos rápidos van a necesitar más cálculos hechos de manera frecuente, y por lo tanto fixedDeltaTime necesitará ser menor o una colisión podría fallar.
  • Physics.solverIterationCount (Administrador de física).
  • Utilice tan pocos objetos Cloth como sea posible.
  • Utilice Rigidbodies solamente dónde sean necesarios.
  • Utilice colliders primitivos en colliders mesh preferidos.
  • Nunca mueva un collider estático (ie un collider sin un Rigidbody) ya que causa un gran golpe de rendimiento. Se muestra en el Profiler (Perfilador) como "Static Collider.Move’ pero el procesamiento en realidad está en Physics.Simulate. Si es necesario, agregue un RigidBody y configure isKinematic a true.
  • En Windows usted puede utilizar la herramienta de profiling (perfilamiento) AgPerfMon de NVidia configurada a obtener más detalles si se necesita.

Android

GPU

Estas son las arquitecturas móviles populares. Esto es diferente a los vendedores de hardware en el espacio de PC/consola, y muy diferente a las arquitecturas de GPU a las GPUS “usuales”.

  • ImgTec PowerVR SGX - Basado en Tile (tejas), deffered (diferido): renderiza todo en pequeñas tejas (como 16x16), shade solamente los pixeles visibles
  • NVIDIA Tegra - Classic: Renderiza toda
  • Qualcomm Adreno - Tiled (tejas): Renderiza todo en tejas, ingeniado en grandes tejas (como 256k). Adreno 3xx puede cambiarse a uno tradicional.
  • ARM Mali Tiled: Renderiza todo en teja, ingeniado en pequeñas tejas (como 16x16)

Gaste un poco de tiempo buscando acercamientos diferentes de renderización y diseñe su juego de acuerdo a esto. Preste una atención especial al ordenamiento. Defina los dispositivos de baja gama soportados tan pronto en el ciclo de diseño. Pruebe en estos con el profiler (perfilador) a medida que usted diseña su juego.

Use una compresión de texturas específica para la plataforma.

Lecturas adicionales

Resolución de la Pantalla

Versión Android

iOS

GPU

Solamente la arquitectura PowerVr (basado ten teja deferred) para preocuparse.

  • ImgTec PowerVR SGX. Tile based (basado en tejas), deferred: renderiza todo en tejas, shade solamente los pixeles visibles.

Esto quiere decir:

  • Los mipmaps no son necesarios.
  • Antialiasing y ansi son lo suficientemente baratos, no se necesita en iPad 3 en algunos casos.

Y los contras:

  • Si los datos de vértice por frame (número de vértices * almacenamiento requerido después del vertex shader) excede los buffers asignados internamente por el drive, la escena se tiene que “dividir”, lo cual le cuesta al rendimiento. El driver podría asignar un buffer más grande en este punto, o usted podría necesitar reducir su cuenta de vértices. Esto se vuelve aparente en iPad2 (iOS 4.3) al rededor de 100 mil vértices con unos shaders que parecen complicados.
  • TBDR necesita más transitores asignados para el tiling (poner tejas) y las partes deferred (diferidas), dejando menos transitores conceptualmente para “rendimiento raw”. Es muy difícil (i.e. prácticamente imposible) obtener un tiempo de GPU para un draw call en TBDR, haciendo el profiling (perfilamiento) difícil.

Lecturas adicionales

Resolución de la Pantalla

Versión iOS

Objetos Dinámicos

Asset Bundles

  • Los Asset Bundles son cached en un dispositivo a cierto limite
  • Cree utilizando el API del Editor
  • Cargue utilizando WWW API: WWW.LoadFromCacheOrDownload o como un recurso AssetBundle.CreateFromMemory o AssetBundle.CreateFromFile
  • Descargue utilizando AssetBundle.Unload. Hay una opción para descargar el bundle, pero mantenga el asset cargado de esto. También mate todos los assets cargados incluso si están referenciados en la escena.
  • Resources.UnloadUnusedAssets descarga todos los assets que ya no están referenciados en la escena. Entonces recuerde matar las referencias a los assets que usted ya no necesita. Las variables públicas y estáticas son nunca recolectadas por el garbage collected.
  • Resources.UnloadAsset descargar un assets especifico de memoria. Puede ser re-descargado desde el disco si se necesita.

Hay alguna limitación para el número de descargas de AssetBundle a la vez en iOS? (e.g Podemos descargar de manera segura 10 assetbundles al mismo tiempo (o en cada frame)?)

Las descargas son implementadas vía la API async proporcionada por OS, por lo que OS decide qué tantos hilos (threads) necesitan ser creados para descargas. Cuando se lance múltiples descargas concurrentes, usted debería tener en cuenta el bando de ancha total del dispositivo que pueda soportar y la cantidad de memoria disponible. Cada descarga concurrente asigna su propio buffer temporal, por lo que debería tener cuidado de no quedarse sin memoria.

Recursos

  • Los Assets necesitan ser reconocidos por Unity para ser colocados en una construcción.
  • Agrega una extensión de archivo .bytes a cualquier bytes ray que usted quiere que Unity reconozca como datos binarios.
  • Agregue una extensión de archivo .txt a cualquier archivo texto que usted quiere que Unity reconozca como un asset de texto
  • Los recursos son convertidos a un formato de plataforma en el tiempo de construcción.
  • Resources.Load()

Lista de cuestiones tontas

  • Texturas sin una compresión apropiada
  • Diferentes soluciones para diferentes casos, pero esté seguro de comprimir las texturas al menos de que usted esté seguro que no debería.
  • ETC/RGBA16 - predeterminado para android puede se puede ajustar dependiendo en el proveedor de GPU. El mejor acercamiento es utilizar ETC dónde sea posible. Las texturas Alpha pueden utilizar dos archivos ETC con un canal siendo para el alpha
  • PVRTC - predeterminado para IOS, bueno para la mayoría de casos
  • Texturas teniendo Get/Set pixels habilitado - dobla la huella, desmarque al menos de que Get/Set sea necesitado
  • Texturas cargadas desde JPEG/PNGs en tiempo de ejecución serán des-comprimidas
  • Archivos mp3 grandes marcados como des-comprimidos en la carga
  • Additive scene loading
  • Assets sin utilizar que permanecen sin limpiar en memoria.
  • Si de manera aleatoria crashes (falla), intente un devkit (kit de desarrollo) o un dispositivo con 2 GB de memoria (como un Ipad 3).

A veces no hay nada en la consola, simplemente un crash aleatorio

  • Un llamado rápido de script y stripping puede llevar a crashes aleatorios en iOS. Intente sin estos.
Profiling
Practical guide to optimization for mobiles