Interpretación del seguimiento de rendimiento de Multicore (Eclipse / Android)

Estoy trabajando en un juego de Android, y empecé a notar un poco de lentitud durante el desarrollo por lo que quería tratar de utilizar multithreading para la diversión y el aprendizaje.

Mi aplicación tiene 3 subprocesos:

  1. Hilo de la interfaz de usuario (debe estar en su mayor parte inactivo)
  2. Hilo de lógica del juego
  3. Hilo de gráficos

Minimicé la sección crítica entre los subprocesos 2 y 3 lo mejor que pude, con la idea de que la lógica del juego podría actualizarse independientemente del subproceso de renderizado y luego al final de ambos subprocesos podría tener una ventana corta como posible donde presionaré a todos Las actualizaciones gráficas del hilo lógico al bucle del juego. Esto debería permitir que los dos hilos funcionen de forma independiente durante la mayoría de las veces. En teoría suena como una victoria de rendimiento.

Sin embargo, una vez que llegué a implementar, mi rendimiento dio un gran buceo. Es mucho peor que antes, un bucle de actualización y renderizado está tomando como 50 ms (20fps), por lo que parece basura. Esto es sólo renderizar unos 20 triángulos y quizás 20 cuadrículas texturizadas, una carga de trabajo realmente simple (tengo miedo de pensar en lo que será cuando implemento los gráficos adecuados).

De todos modos tomé un rastro de DDMS en androide para perfilar donde las cosas iban mal o podría ser mejorado.

Traza1 Http://i.stack.imgur.com/DDUYE.png

Esta es una vista de aproximadamente 3 marcos de mi juego. Hasta ahora parece estar haciendo aproximadamente lo que esperaba. Las partes que están resaltadas en azul es la sección bloqueada, que mira a la derecha (mantiene el glThread en su mayoría esperando mientras está bloqueado). Sin embargo, una vez que lo desbloqueo debería ver ambos hilos trabajando simultáneamente, y parece que lo son, pero si miro más cerca:

Traza 2 Http://i.stack.imgur.com/vukXQ.png

Estoy haciendo mi desarrollo en un teléfono de doble núcleo, pero si entiendo el rastro correcto no parece que nunca está haciendo nada en paralelo, y lo que es peor, parece estar cambiando el hilo activo cientos de veces por milisegundo! (A menos que esté interpretando esto incorrectamente). Todo este cambio de contexto parece que sería horrible para el rendimiento, así que no estoy seguro de por qué querría cambiar de ida y vuelta tan rápido.

Así que después de mi larga explicación, me pregunto algunas cosas:

  1. ¿Es correcto mi entendimiento, que los rectángulos rellenos en la huella son los hilos activos, y las líneas coloreadas son hilos durmientes? De lo contrario, ¿qué significan?
  2. ¿Por qué no veo mis hilos ejecutándose simultáneamente en un teléfono supuestamente de doble núcleo?
  3. ¿Por qué está cambiando los hilos activos tan rápidamente?
  4. En DDMS obtengo la advertencia "ADVERTENCIA: un depurador está activo, los resultados del rastreo de métodos serán sesgados". ¿Es esto algo de qué preocuparse? ¿Cómo puedo deshacerme de esta advertencia? (He lanzado la aplicación a través de Ejecutar, no a través de Debug si hace una diferencia)

Muy buena pregunta, permítanme comenzar con las respuestas:

  1. Has mezclado subprocesos / methods / activeMethod. Cada línea de traceview es hilo (y si has nombrado tus hilos, verás su nombre en el lado izquierdo, como "GL Thread", "main", etc.). Los rectángulos (de color) representan los métodos de ejecución activos dentro de cada hilo, mientras que las líneas de color representan métodos "detenidos" en el hilo. Por "pausado", quiero decir "el método todavía se está ejecutando, pero el contexto fue cambiado a otro hilo, y cuando el contexto cambió de nuevo a este hilo, este método continuará trabajando." En la terminología que ha utilizado en su pregunta, Las líneas son los métodos del hilo de dormir, y el rectángulo es el método de ejecución del hilo activo.Puede encontrar más información acerca de DDMS traceview aquí .
  2. La distribución de hilos entre núcleos es otra historia y depende en gran medida de los mecanismos subyacentes del sistema operativo Android. En primer lugar, asegúrese de que el objetivo Android OS se inicia con la opción SMP (Symmetric Multi-Processing), que es el caso por defecto para los teléfonos multicore, supongo :), pero no soy experto en esas cosas. Algunas palabras sobre SMP se puede encontrar aquí .
  3. El cambio de subprocesos depende del programador de procesos / subprocesos del sistema operativo, prioridad de subprocesos, etc. Más información acerca de estas cosas se pueden encontrar en estas respuestas.
  4. Incluso si ejecuta la aplicación en modo no depurador, cuando se conecta con DDMS y hace las cosas como el perfil de métodos, activará las partes de depuración de davlik vm. Más detalles sobre la depuración aquí, sección "Implementación".

Espero que encuentre esta respuesta útil.

Gracias por la pregunta. Una respuesta completa por un iniciado me será de ayuda también. Voy a decir lo que sé.

  • Algunos (todos?) Teléfonos tienen una opción para activar / desactivar el núcleo segundo. ¿Ha comprobado que el suyo está encendido?

  • En mi propia aplicación he notado que simplemente pasando de un hilo a dos (en un núcleo) sin cambio en el trabajo total realizado causa un factor de desaceleración de 1,5, por lo que claramente el enhebrado tiene un costo.

  • Ha sido en las noticias que Intel está llamando a Google en la implementación deficiente de roscado multicore:

    http://www.pcworld.com/article/257307/dual_core_processors_wasted_on_android_intel_claims.html

    Sus resultados validan esto.

  • Otra cosa a tener en cuenta es que multi-core no es multi-procesador. Está compartiendo ancho de banda de memoria caché y controlador de memoria entre núcleos. Uno puede detenerse mientras espera a que el otro termine con un recurso compartido, en particular para escribir en líneas de caché compartidas. Sin embargo este efecto no debe explicar el solo-threading que usted está viendo.

  • SystemClock.sleep () vs. Thread.sleep () mientras espera un bucle de semáforo
  • Solicitud de HttpClient simultánea utilizando varias AsyncTasks
  • Creación de vistas dentro de un hilo de trabajo
  • ¿Es una buena práctica crear AsyncTask anónima para paralelo pequeño proceso de congelación conocido?
  • ProgressDialog animaciones pausas en grandes setText ()
  • Reproductor multimedia de Android que provoca mensaje de "hilo muerto"
  • ¿Por qué estoy recibiendo: threadid = 3: reaccionar a la señal 3 y congelación de juego (AndEngine)?
  • Detenga el subproceso Java que llama a la función JNI
  • Bloqueo de hilo principal de Android que bloquea hilo de WebView
  • Método de dibujo de Android que se ejecuta lento
  • Cómo detener el hilo de ASyncTask en android
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.