WP7 Problemas de rendimiento con Struct (II / II)

Realicemos un pequeño benchmark para poder evaluar cual es la pérdida de rendimiento obtenido, el cual se producirá por:

CPU: Tiempo empleado en gestionar las llamadas (realizar las copias de las estructuras)

Para el test vamos a crear un proyecto para Windows Phone 7.1 con Visual Studio, y luego lo analizaremos con el profiler de WP7 corriendo directamente en un dispositivo real.

La demo será muy simple, colocaremos un bucle en el método Draw que es donde más operaciones con struct se suelen hacer, y dentro del bucle realizaremos una llamada a un método al cual se le pasarán 50 matrices por parámetro (esto es para probar que realmente el problema viene por las copias de struct).

 

//Iteraciones será igual a 5000 para simular carga de trabajo
for (int i = 0; i < iterations; i++)
{
   //Llamada al método
}

Crearemos dos versiones del método que va dentro del bucle, en uno pasaremos las matrices por valor (lo normal) y en el otro lo haremos por referencia.

 

Por valor:

private void UpdateMatrices(Matrix world0, Matrix view0, Matrix projection0,
                                     Matrix world1, Matrix view1, Matrix projection1,
                                     Matrix world2, Matrix view2, Matrix projection2,
                                     Matrix world3, Matrix view3, Matrix projection3,
                                     Matrix world4, Matrix view4, Matrix projection4,
                                     Matrix world5, Matrix view5, Matrix projection5,
                                     Matrix world6, Matrix view6, Matrix projection6,
                                     Matrix world7, Matrix view7, Matrix projection7,
                                     Matrix world8, Matrix view8, Matrix projection8,
                                     Matrix world9, Matrix view9, Matrix projection9,
                                     Matrix world10, Matrix view10, Matrix projection10,
                                     Matrix world11, Matrix view11, Matrix projection11,
                                     Matrix world12, Matrix view12, Matrix projection12,
                                     Matrix world13, Matrix view13, Matrix projection13,
                                     Matrix world14, Matrix view14, Matrix projection14,
                                     Matrix world15, Matrix view15, Matrix projection15,
                                     Matrix world16, Matrix view16, Matrix projection16,
                                     Matrix world17, Matrix view17, Matrix projection17,
                                     Matrix world18, Matrix view18, Matrix projection18,
                                     Matrix world19, Matrix view19, Matrix projection19,
                                     Matrix world20, Matrix view20, Matrix projection20,
                                     Matrix world21, Matrix view21, Matrix projection21,
                                     Matrix world22, Matrix view22, Matrix projection22,
                                     Matrix world23, Matrix view23, Matrix projection23,
                                     Matrix world24, Matrix view24, Matrix projection24,
                                     Matrix world25, Matrix view25, Matrix projection25,
                                     Matrix world26, Matrix view26, Matrix projection26,
                                     Matrix world27, Matrix view27, Matrix projection27,
                                     Matrix world28, Matrix view28, Matrix projection28,
                                     Matrix world29, Matrix view29, Matrix projection29,
                                     Matrix world30, Matrix view30, Matrix projection30,
                                     Matrix world31, Matrix view31, Matrix projection31,
                                     Matrix world32, Matrix view32, Matrix projection32,
                                     Matrix world33, Matrix view33, Matrix projection33,
                                     Matrix world34, Matrix view34, Matrix projection34,
                                     Matrix world35, Matrix view35, Matrix projection35,
                                     Matrix world36, Matrix view36, Matrix projection36,
                                     Matrix world37, Matrix view37, Matrix projection37,
                                     Matrix world38, Matrix view38, Matrix projection38,
                                     Matrix world39, Matrix view39, Matrix projection39,
                                     Matrix world40, Matrix view40, Matrix projection40,
                                     Matrix world41, Matrix view41, Matrix projection41,
                                     Matrix world42, Matrix view42, Matrix projection42,
                                     Matrix world43, Matrix view43, Matrix projection43,
                                     Matrix world44, Matrix view44, Matrix projection44,
                                     Matrix world45, Matrix view45, Matrix projection45,
                                     Matrix world46, Matrix view46, Matrix projection46,
                                     Matrix world47, Matrix view47, Matrix projection47,
                                     Matrix world48, Matrix view48, Matrix projection48,
                                     Matrix world49, Matrix view49, Matrix projection49)
        {
                   //Dentro no hacemos nada
         }

Por referencia:

private void UpdateMatricesOptimized(ref Matrix world0, ref Matrix view0, ref  Matrix projection0,
                                             ref Matrix world1, ref Matrix view1, ref  Matrix projection1,
                                             ref Matrix world2, ref Matrix view2, ref  Matrix projection2,
                                             ref Matrix world3, ref Matrix view3, ref  Matrix projection3,
                                             ref Matrix world4, ref Matrix view4, ref  Matrix projection4,
                                             ref Matrix world5, ref Matrix view5, ref  Matrix projection5,
                                             ref Matrix world6, ref Matrix view6, ref  Matrix projection6,
                                             ref Matrix world7, ref Matrix view7, ref  Matrix projection7,
                                             ref Matrix world8, ref Matrix view8, ref  Matrix projection8,
                                             ref Matrix world9, ref Matrix view9, ref  Matrix projection9,
                                             ref Matrix world10, ref Matrix view10, ref Matrix projection10,
                                             ref Matrix world11, ref Matrix view11, ref Matrix projection11,
                                             ref Matrix world12, ref Matrix view12, ref Matrix projection12,
                                             ref Matrix world13, ref Matrix view13, ref Matrix projection13,
                                             ref Matrix world14, ref Matrix view14, ref Matrix projection14,
                                             ref Matrix world15, ref Matrix view15, ref Matrix projection15,
                                             ref Matrix world16, ref Matrix view16, ref Matrix projection16,
                                             ref Matrix world17, ref Matrix view17, ref Matrix projection17,
                                             ref Matrix world18, ref Matrix view18, ref Matrix projection18,
                                             ref Matrix world19, ref Matrix view19, ref Matrix projection19,
                                             ref Matrix world20, ref Matrix view20, ref Matrix projection20,
                                             ref Matrix world21, ref Matrix view21, ref Matrix projection21,
                                             ref Matrix world22, ref Matrix view22, ref Matrix projection22,
                                             ref Matrix world23, ref Matrix view23, ref Matrix projection23,
                                             ref Matrix world24, ref Matrix view24, ref Matrix projection24,
                                             ref Matrix world25, ref Matrix view25, ref Matrix projection25,
                                             ref Matrix world26, ref Matrix view26, ref Matrix projection26,
                                             ref Matrix world27, ref Matrix view27, ref Matrix projection27,
                                             ref Matrix world28, ref Matrix view28, ref Matrix projection28,
                                             ref Matrix world29, ref Matrix view29, ref Matrix projection29,
                                             ref Matrix world30, ref Matrix view30, ref Matrix projection30,
                                             ref Matrix world31, ref Matrix view31, ref Matrix projection31,
                                             ref Matrix world32, ref Matrix view32, ref Matrix projection32,
                                             ref Matrix world33, ref Matrix view33, ref Matrix projection33,
                                             ref Matrix world34, ref Matrix view34, ref Matrix projection34,
                                             ref Matrix world35, ref Matrix view35, ref Matrix projection35,
                                             ref Matrix world36, ref Matrix view36, ref Matrix projection36,
                                             ref Matrix world37, ref Matrix view37, ref Matrix projection37,
                                             ref Matrix world38, ref Matrix view38, ref Matrix projection38,
                                             ref Matrix world39, ref Matrix view39, ref Matrix projection39,
                                             ref Matrix world40, ref Matrix view40, ref Matrix projection40,
                                             ref Matrix world41, ref Matrix view41, ref Matrix projection41,
                                             ref Matrix world42, ref Matrix view42, ref Matrix projection42,
                                             ref Matrix world43, ref Matrix view43, ref Matrix projection43,
                                             ref Matrix world44, ref Matrix view44, ref Matrix projection44,
                                             ref Matrix world45, ref Matrix view45, ref Matrix projection45,
                                             ref Matrix world46, ref Matrix view46, ref Matrix projection46,
                                             ref Matrix world47, ref Matrix view47, ref Matrix projection47,
                                             ref Matrix world48, ref Matrix view48, ref Matrix projection48,
                                             ref Matrix world49, ref Matrix view49, ref Matrix projection49)
        {
            //No hacemos nada
        }

Resultados:

Una vez tenemos el benchmark montado, lo ejecutamos sobre un dispositivo y le conectamos el profiler, y este es el resultado:

WP_001061

 

 

WP_001062

 

 

 

benchmark

 

En la primera zona, estaba realizando las 5000 iteraciones llamando al método que hace el paso de parámetros por valor, y en la segunda etapa estaba usando el método que realiza el paso de parámetros por referencia.

 

Conclusiones

Como podemos ver, el paso de parámetros se está “comiendo” literalmente la CPU en la primera zona. Es decir, la CPU está trabajando al 100% solo en realizar las llamadas con las respectivas copias de structs, no hay tiempo de CPU para el código de nuestro juego. Sin embargo, en la segunda zona, realizando la misma operación, tenemos una CPU liberada para ejecutar nuestro código.

 

Este último dato asusta bastante, así que es importante que todo desarrollador de Windows Phone 7 lo conozca y tenga todo esto presente.

 

Proyecto de Visual Studio

Publicado por

jcanton

Javier is a Computer Science Engineer who has always had a passion for 3D graphics and software architecture. He learned C# almost at the same time as he learned to talk, and his first word was "base". He enjoys imparting talks about technology and has contributed in many important software and video game events. He has participated in multitude of software projects involving multitouch technologies, innovative user interfaces, augmented reality, and video games. Some of these projects were developed for companies such as Microsoft, Syderis, and nVidia. His professional achievements include being MVP for Windows DirectX and DirectX XNA for the last eight years, Xbox Ambassador, as well as Microsoft Student Partner and Microsoft Most Valuable Student during his years at college. Currently he works at Plainconcepts and he is the development team lead at WaveEngine project.

4 comentarios en “WP7 Problemas de rendimiento con Struct (II / II)”

  1. Hola,

    Interesante. Yo creo que la CPU se le va, como tú dices, en copiar los structs, pero nunca debería saltarte el recolector de basura (como estás viendo).

    Si los structs se crean en el stack (y no el heap), la memoria que ocupan se libera automáticamente al salir del método, ¿no? Debería ser una simple operación de decrementar el puntero de la cima de la pila, no hace falta pasar el GC para eso.

    Saludos,

    Juanma.

  2. Buenas Juanma, me alegro que te hayas animado a escribir XD. Pues tienes toda la razón dificilmente en ese ejemplo iba a saltar el recolector de basura ya que todas esas matrices se crean en el stack, ahora editaré la parte de las conclusiones para cambiar esto.

    Por otra parte, comentarte que no todas las struct se almacenan en el stack, es un poco más complejo. Las struct que son campos de una clase por ejemplo se almacenan en el heap junto a la instancia de la clase.

    Me gustaría escribir también sobre esto algún día.

    Gracias por el apunte.

  3. Tienes razón, no todas struct viven en el stack y de las que viven en el stack, no todo viven en el stack. Por ejemplo, si contienen referencias a un objeto la referencia vivirá en el stack pero el objeto en el heap. Desde luego es un tema interesante, a ver si te animas a escribir un post sobre eso que mucha gente no lo tiene muy claro.

    Por cierto, lo de pasar los structs por ref me ha recordado a mis tiempos mozos cuando en Pascal pasabas los arrays por referencia para no generar un stack overflow… ¡qué mayor es uno! 🙂

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *