overhead Computation en C # - Uso getters / setters vs. Modificación de matrices directamente y fundición velocidades

StackOverflow https://stackoverflow.com/questions/3018536

Pregunta

Yo iba a escribir un post largo aliento, pero voy a hervir aquí abajo:

Estoy tratando de emular el estilo gráfico de la vieja escuela de la NES a través de XNA. Sin embargo, mi FPS es lento, tratando de modificar 65K píxeles por imagen. Si tan solo bucle a través de todos los 65 mil píxeles y los puso a un poco de color arbitrario, consigo 64fps. El código que he hecho para parecer en marcha lo que los colores deben ser colocados donde, consigo 1FPS.

Creo que es debido a mi código orented a objetos.

En este momento, tengo cosas divididos en seis clases, con getters / setters. Supongo que estoy llamando a al menos 360 K captadores por cuadro, que creo que es un montón de gastos generales. Cada clase contiene o / y-1D o 2D o matrices que contienen enumeraciones personalizados, int, Color o Vector2D, bytes.

¿Qué pasa si he combinado todas las clases en una sola, y se accede a los contenidos de cada matriz directamente? El código sería un desastre, y zanja los conceptos de orientación a objetos de codificación, pero la velocidad puede ser mucho más rápido.

También estoy no está preocupado por violaciónes de acceso, ya que cualquier intento de obtener / poner los datos en las matrices se hace en bloques. Por ejemplo, toda la escritura de matrices se llevará a cabo antes de que se accede a los datos de ellos.


En cuanto a la fundición, me dijo que estoy usando enumeraciones personalizados, int, Color y Vector2D, bytes. ¿Qué tipos de datos son más rápido de usar y de acceso en el .NET Framework, XNA, XBox, C #? Creo que la fundición constante podría ser una causa de la desaceleración aquí.

También, en lugar de usar las matemáticas para averiguar qué datos de los índices deben ser colocados en, he utilizado precalculados de búsqueda mesas, así que no tengo que usar la multiplicación constante, suma, resta, división por cuadro. :)

¿Fue útil?

Solución

Hay una presentación excelente de la GDC 2008 que vale la pena leer si usted es un desarrollador de XNA. Se llama La comprensión de XNA Framework rendimiento .

Para su arquitectura actual - que en realidad no han descrito lo suficientemente bien como para dar una respuesta definitiva - es probable que están haciendo demasiado innecesaria "cosas" en un bucle estrecho. Si tuviera que adivinar, diría sugerir que su método actual se agitaba la memoria caché -. Que debe arreglar su diseño de datos

En el caso ideal que debería tener una agradable gran variedad de pequeñas-como-posible Tipos de valor (structs no clases), y un bucle en gran medida inline que empujones datos en él de forma lineal.

( Aparte : en relación con lo que es rápido: Entero y las matemáticas de punto flotante es muy rápido - en general, no se debe utilizar tablas de consulta llamadas a funciones son bastante rápido - hasta el punto de que la copia de gran tamaño. estructuras cuando se los pasan serán más significativos El JIT inline captadores y definidores simples -. a pesar de que usted no debe depender de él para nada más en línea bucles muy ajustados -. como su blitter)

Sin embargo - incluso si optimiza - chupa su arquitectura actual. Lo que está haciendo va en contra de cómo un modernas obras de GPU. Usted debe cargar tus sprites en su GPU y dejar que su escena compuesta.

Si se quiere manipular sus sprites en un nivel de píxeles (por ejemplo: el intercambio de paletas como se ha mencionado), entonces debería ser el uso de los sombreadores de píxeles. La CPU en el 360 (y en PC) es rápido, pero la GPU es mucho más rápido cuando estás haciendo algo como esto!

El Sprite Efectos muestra de XNA es un lugar bueno para empezar.

Otros consejos

¿Ha perfilado su código para determinar dónde está la desaceleración? Antes de ir a la reescritura de la aplicación, se debe conocer al menos los que tienen que ser reescrito partes.

Me fuertemente sospechoso que la sobrecarga de los descriptores de acceso y las conversiones de datos es trivial. Es mucho más probable que sus algoritmos están haciendo un trabajo innecesario, los valores que podían almacenar en caché, y otras cosas que se pueden abordar sin volar su diseño objeto recalcular.

¿Usted está especificando un color y tal para cada píxel o algo? Si ese es el caso, creo que realmente debería pensar en la arquitectura un poco más. Empezar a utilizar sprites que acelerar las cosas.

editar

Está bien creo que lo que su solución podría ser la carga de varios sprites con diferentes colores (un sprite de unos pocos píxeles) y volver a usar esos. Es más rápido que apuntan al mismo sprites de asignar un color diferente para cada píxel como el sprite ya ha sido cargado en la memoria

Al igual que con cualquier problema de rendimiento, se debe perfilar la aplicación para identificar los cuellos de botella en lugar de tratar de adivinar. Tengo serias dudas de que los captadores y definidores están en la raíz de su problema. El compilador casi siempre inlines este tipo de funciones. También tengo curiosidad lo tienes en contra de las matemáticas. La multiplicación de dos números enteros, por ejemplo, es una de las cosas más rápido que la computadora puede hacer.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top