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:
- 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.
- 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.
- 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.
- 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
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
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
+1 para pregunta/artículo muy interesante – Ryan