2012-08-12 14 views
7

Así que quería convertir mi juego de PC para trabajar en la Xbox 360. Funcionó muy bien en la PC, con un Intel Core 2 Quad a 2.40Ghz y una Radeon 4850 512MB.PC XNA Game convertido a Xbox 360 - Enormes problemas de rendimiento

Lo porté a la Xbox, y desde el principio, hubo algún problema con la invarianza y la herencia con respecto a la importación de listas, así que simplemente usé el método LINQ llamado .Cast <>().

Si ese método es da un gran sobrecarga, que me haga saber, porque no puedo desplegar Análisis de rendimiento en el 360, por alguna razón, lo más probable, ya que juega en el 360.

Luego otro problema vino, y se era un buen System.OutOfMemoryException. Las texturas de mi skybox eran 4096x4096, por lo que reducirlas a la mitad eliminaba ese error. Aunque es extraño, tenían solo 3MB x 6, por lo que no deberían usar gran parte de los 512MB disponibles.

Entonces, cuando todos esos problemas se borraron del camino, se introdujo un bonito 1 fotograma por 2 segundos. A continuación, se bloquea después de 1 minuto de juego, un "Código 4" lo que sea que eso signifique.

Funciona como un powerpoint. Aquí hay algunas imágenes de análisis de rendimiento de juegos de PC. Ellos no están mal.

CPU: http://i.imgur.com/JYx7Z.png RAM: http://i.imgur.com/C29KN.png Y 72% = 150MB, tenedlo en cuenta.

Espero que cualquiera aquí tenga alguna experiencia sobre este tema. Francamente, soy todo oídos.

Respuesta

11

La causa raíz de sus problemas de rendimiento es casi seguro porque está asignando memoria mientras se ejecuta su juego (después del inicio, durante el ciclo Draw/Update).

En Windows esto está bien. El recolector de basura en Windows es generacional (solo limpiará objetos nuevos cuando sea posible) y extremadamente rápido. También es inteligente sobre cuándo elige ejecutarse.

El recolector de basura en la Xbox 360, por otro lado, es completamente basura. Se ejecuta por cada 1 MB de memoria asignada. Comprueba todo el montón administrado cuando se ejecuta. Y es bastante lento para arrancar.

Así que la respuesta es nunca asignar memoria mientras el juego está en estado de ejecución.

Hay una buena publicación en el blog sobre este here. (Se describe también la alternativa de no asignar memoria - que es reducir la complejidad del montón - que en realidad es muy difícil de implementar y no lo recomiendo.)

  • Usted tendrá que quitar cosas como LINQ, como los objetos de consulta que crea son objetos de montón, como son los delegados que requiere con frecuencia. Use bucles simples en su lugar.
  • Si está asignando sus propios tipos de referencia en draw/update, tendrá que convertir a usar tipos de valores cuando sea posible o agregar pooling de objetos.
  • Crear objetos string es otra fuente común de asignaciones de memoria; en su lugar, puede reutilizar un StringBuilder y representarlo directamente.
  • La conversión de cosas (especialmente: números) a cadenas, incluso para StringBuilder asignará memoria. Necesita escribir/encontrar alternativas sin asignación.My answer to this similar question tiene uno para int.

La mejor forma de diagnosticar, donde se están asignando memoria es ejecutar el juego con el CLR Profiler en Windows. Esto le indicará dónde y cuándo se asignará la memoria. Simplemente optimice hasta que no esté asignando.

(O hasta que esté asignando de manera confiable menos de 1MB por nivel/mapa/habitación/lo que sea, y haga un GC manual durante un tiempo donde sea apropiado tartamudear, como una pantalla de carga estática o un fundido a negro .)

El código 4 es una excepción no controlada. Necesita instalar un controlador de excepciones de nivel superior que emita un mensaje, o ejecute su juego en el depurador, para determinar la causa.

Finalmente: Esa es probablemente la comprimida tamaño de sus texturas (usando PNG o JPEG o similar). Si sus texturas no están comprimidas, 4096 × 4096 × 6 × 4 bytes = 384MB. Esto es enorme, no es de extrañar que se haya quedado sin memoria. Puede comprimirlos con DXT1 y hacerlos 6 veces más pequeños (instructions, wiki). También podría reducir su resolución. ¿Y necesitas la cara inferior en absoluto?

+1

Muchas gracias, después de buscar mucho encontré una respuesta similar a la tuya, y cuando ejecuté mi Perfil CLR encontré que estaba asignando alrededor de 60MB por fotograma ... no es bueno. Es porque agrego todos los objetos colisibles de mi juego a una lista y luego los arrojo a un hilo de colisión en cada cuadro. Podría convertirlo en una lista estática, donde solo es una referencia, lo que probablemente haré, pero luego tengo la posibilidad de un retraso de colisión. Pero supongo que es la única opción. –

Cuestiones relacionadas