2012-03-02 14 views
5

Por lo tanto, básicamente intento implementar una extensión nativa de AIR que realice la simulación de física en C con interfaces a través de Actionscript.Enhebrar Box2D con pthreads

He pasado por bastantes iteraciones que enumeraré a continuación por interés y estoy en lo que creo que podría ser mi último intento para que esto funcione de una manera más eficiente.

En definitiva, estoy buscando ayuda sobre cómo debería configurar un entorno de enhebrado para ejecutar la simulación de Box2D en un hilo separado y luego realizar un sondeo de estado en AS3.

Métodos:

  1. de fuerza bruta:

En este método simplemente poner en C de AS3 y decirle que cree un mundo y pasarlo unas cajas para añadir a este mundo. Cada fotograma en AS3, llamo a C para decirle al mundo que Avance, luego recorro todos los cuerpos del mundo, obtengo su posición y rotación, los convierto en objetos actionscript y los coloco en una matriz actionscript y luego los envío a AS3. Una vez allí, recorro la matriz de retorno y asigno esos valores de posición y rotación a mis sprites para que se actualicen visualmente.

Los resultados son realmente bastante decentes con aproximadamente 116 cajas que se agregan antes de que la velocidad de fotogramas sufra. Esto se compara con 30 cajas en una implementación pura de AS3. Tenga en cuenta que estas estadísticas están en modo de depuración. En el modo de lanzamiento, ambos llegan a aproximadamente 120 cajas. Hay poca diferencia entre la implementación de AS3 y la implementación de Extensión nativa.

  1. ByteArray Sharing

Con el fin de mejorar el rendimiento decidí que sería una buena idea para tratar de limitar la cantidad de datos que están siendo movilizados a través de C y AS3 . El soporte de ANE comparte el espacio de memoria de una matriz de bytes y así enviaría ByteArray creado en AS3 a C y tengo C simplemente actualice ByteArray. Esto nos evita tener que construir objetos AS3 en C y devolverlos. Cada fotograma, AS3 simplemente necesita iterar a través de ByteArray y ver qué C ha escrito en él y luego asignar esos valores a los sprites para establecer el estado visual.

Los resultados aquí son lamentablemente casi iguales. Las mejoras son solo marginales.

  1. Objeto Configuración directa de C

Otra cosa ANE de son capaces de está estableciendo la propiedad de un objeto que vive en AS3. En este sentido, mi objetivo fue eliminar la sobrecarga de la transferencia de datos a AS3, el bucle a través de los cuerpos para recopilar datos en C y el bucle en AS3 para asignar los valores. Modifiqué directamente el código de Box2D para que, cuando se cambiaran los valores, escribiera los nuevos valores de rotación x, y, directamente en el Sprite correspondiente.

Los resultados son sorprendentes en cantidades muy bajas de objetos, ya que la llamada para establecer estas propiedades es muy inferior a un milisegundo. El problema es que esto se escala linealmente y alrededor de 90 o más objetos, la sobrecarga es demasiado grave y las cosas comienzan a disminuir.

  1. enhebrar

En este punto, estaba un poco perplejo. Hay una sobrecarga en la recopilación de datos, hay un costo en C para iterar y construir los datos a devolver y hay un costo en AS3 para iterar y asignar valores a los sprites.

Obviamente tiene que haber una compensación, por lo que mi solución actual es la mejor que puedo encontrar por ahora.

En el lado AS3, usted llama a C para crear su mundo, llama para agregar un cuadro a ese mundo, y llama para decirle a C que desea una actualización de sus datos. Cuando se crean cajas en AS3, obtienen una identificación única y se almacenan en un diccionario con la clave que es la identificación.

En el lado C, se crea el mundo y se genera un nuevo pthread para hacer el Paso. Esencialmente simulando el mundo en otro hilo. Después de los pasos, reúne todos los datos y los escribe en una matriz doble. Entonces lo hace una y otra y otra vez. Simplemente simula para siempre básicamente en su propio hilo.

Cuando llamamos a C para agregar un nuevo cuadro, necesito crear un nuevo cuadro y agregarlo a ese mundo. Dado que el mundo está avanzando, esto podría causar problemas, lo que significa que necesito usar mutexes, estoy bastante seguro.

Lo mismo cuando llamamos para actualizar los valores en AIR, quiero hacer una memcpy de la matriz de dobles en mi AS3 bytearray y luego recorrer el bytearray para establecer los valores en el visual.

Los mutex me estaban dando problemas, así que básicamente implementado mi propia que se puede ver a continuación ... y reírse :)

Sin embargo de que funcionara, pero no tan rápido como me gusta demasiado. Alrededor de 90 desaceleramos nuevamente.

¿Alguien tiene alguna idea o sugerencia? ¡Sería muy apreciado!

Código C

El analizador fallaba por lo que he pegado aquí: http://pastebin.com/eBQGuGJX

Código AS3

Lo mismo con el analizador. Solo he incluido el método relevante relacionado con cada cuadro en AS3. http://pastebin.com/R1Qs2Tyt

+0

Tengo una sensación de que esto es el sangrado borde basta con que te vas a encontrar mucha ayuda en cualquier lugar :) También estoy confundido acerca de qué hilos ayudarían. Como cada paso del mundo necesita la información del último paso, no se pueden ejecutar en paralelo, y ejecutar la parte C en un hilo propio no ayuda si el cuello de botella es la transferencia de información a AS3. Dentro de un paso mundial, es posible hacer pequeñas secciones del proceso al mismo tiempo, pero la ganancia de rendimiento es bastante pequeña y el consenso general parece ser que es más ventajoso utilizar núcleos adicionales para renderizado o alguna otra cosa. – iforce2d

+0

Gracias iforce2d. Sí, no estaba seguro de si obtendría una respuesta per se, pero esperaba fomentar la discusión sobre enfoques como este o enlaces al material relevante para obtener explicaciones más detalladas. Mi esperanza era que la simulación podría estar ejecutándose en su propio hilo y el renderizado simplemente aparecería y extraería la última "instantánea" de las posiciones de los objetos y la usaría para renderizar. – Jon

+0

+1 para pregunta/artículo muy interesante – Ryan

Respuesta

3

Había olvidado que tenía esta pregunta. Afortunadamente lo he descubierto.

La idea de utilizar mutexes, etc., ya se había sobrediseñado y no era necesario.

Dado que estamos corriendo en Flash, todo se ejecuta en el hilo principal. Lo que significa que cada flash "frame" manejará de forma nativa cualquier medio, luego nuestro código de cliente que hemos escrito, luego se renderizará en la pantalla y finalmente hará cualquier recolección de basura si es necesario.

Realmente no necesito tener el simulador de física simulando para siempre, simplemente necesito que esté un paso adelante de mi código de cliente.

Entonces, lo que sucede ahora es cuando el Cliente llama al ANE para configurar el mundo, crea un nuevo hilo que simula el mundo y regresa inmediatamente a Flash. Flash continuará haciendo su trabajo de ejecutar el resto del código del cliente y luego renderizar y luego GC.

Luego, en cada cuadro en Flash simplemente podemos llamar al ANE para recuperar los resultados. En el caso de que el hilo de Simulación no haya finalizado, esperamos a través de una unión, extraemos los valores y los devolvemos a Flash. Asegurándose de engendrar otro hilo para el próximo paso antes de regresar del curso.

De esta forma estamos maximizando nuestra eficiencia ya que la simulación está ocurriendo mientras Flash está ocupado haciendo otras cosas sobre las que no tenemos control (como renderizado y GC).

La buena noticia es que el rendimiento casi se duplica con este enfoque. Pasando de aproximadamente 90 recuadros en una implementación AS3 pura sincrónica a aproximadamente 170 recuadros en un enfoque ANE enhebrado.

El cuello de botella finalmente se convierte en la iteración a través de los datos que regresan del ANE y la asignación de esos valores a los objetos de visualización.

Espero que esto ayude a alguien más que estaba buscando algo similar. Hablaré de ello en FITC Toronto a fines de abril para que haya más información y material que pueda postear.

http://www.fitc.ca/events/presentations/presentation.cfm?event=124&presentation_id=1973