2009-04-15 8 views
10

Estoy escribiendo una aplicación DSP en C# (básicamente, un editor multipista). Lo he estado perfilando durante bastante tiempo en diferentes máquinas y he notado algunas cosas "curiosas".Forzar el compilador .NET JIT para generar el código más optimizado durante la puesta en marcha de la aplicación

En mi máquina doméstica, la primera ejecución del ciclo de reproducción ocupa aproximadamente del 50% al 60% del tiempo disponible (supongo que es debido a que el JIT está haciendo su trabajo), y luego para los bucles subsiguientes baja a un consumo estable del 5%. El problema es que, si ejecuto la aplicación en una computadora más lenta, la primera ejecución ocupa más que el tiempo disponible, lo que ocasiona que la reproducción se interrumpa y estropee el audio de salida, lo cual es inaceptable. Después de eso, se reduce a un consumo del 8% -10%.

Incluso después de la primera ejecución, la aplicación sigue llamando rutinas que requieren mucho tiempo de vez en cuando (cada 2 segundos más o menos), lo que hace que el consumo estable del 5% experimente picos muy cortos de 20% -25% . Me he dado cuenta de que si dejo que la aplicación se ejecute durante un tiempo, estos picos también bajarán a un 7% -10%. (No estoy seguro si es debido a que el JIT recompila estas porciones de código).

Tengo un problema serio con el JIT. Si bien la aplicación se comportará bien incluso en máquinas muy lentas, estas 'tormentas compiladoras' van a ser un gran problema. Estoy intentando descubrir cómo resolver este problema y se me ocurrió una idea, que es marcar todas las rutinas "sensatas" con un atributo que le dirá a la aplicación que las 'apriete' de antemano durante la puesta en marcha , por lo que estarán completamente optimizados cuando realmente se necesiten. Pero esto es solo una idea (y tampoco me gusta demasiado) y me pregunto si hay una mejor solución para todo el problema.

Me gustaría escuchar lo que piensan.

(NGEN la aplicación no es una opción, me gusta y quiero todas las optimizaciones JIT yo puede conseguir.)

EDIT:

consumo de memoria y recolección de basura patadas no son un problema, estoy utilizando grupos de objetos y el pico máximo de memoria durante la reproducción es de 304 Kb.

+1

Ayudaría si dijera ** por qué ** NGEN no es una opción; entender el problema es la mitad del trabajo ... –

+0

¿Qué optimizaciones de JIT no están disponibles cuando NGen-ing? – Will

+0

@Marc: NGen la aplicación como último recurso, pero prefiero no usarla si hay una mejor solución disponible. – Trap

Respuesta

16

Puede desencadenar el compilador JIT para compilar todo su conjunto de ensamblajes durante la rutina de inicialización de su aplicación usando el método PrepareMethod ... (sin tener que usar NGen).

Esta solución se describe con más detalle aquí: Forcing JIT Compilation During Runtime.

4

La velocidad inicial de hecho suena como Fusion + JIT, que sería ayudado por ILMerge (para Fusion) y NGEN (para JIT); siempre se puede jugar una pista silenciosa a través del sistema en el inicio para que esto haga todo el trabajo duro sin que el usuario note ninguna distorsión.

NGEN es una buena opción; ¿Hay un motivo que no puedas usar?

Los problemas que mencionan después de la carga inicial de hacer no suenan como si están relacionados con JIT. Tal vez la recolección de basura.

¿Has probado el perfilado? ¿CPU y memoria (colecciones)?

+0

Para mí, la única razón para no utilizar ngen sería que requiere privilegios administrativos durante la instalación, por lo que no se aplica a instalaciones por usuario en redes corporativas. Tal vez esa es la razón del OP también? –

+0

¿Por qué no hacer NGEN como una opción en la instalación, entonces? Entonces, si tienes derechos de administrador, hazlo. De lo contrario, advierte al usuario y no lo hagas. –

3

Como mencionó Marc, los picos en curso no suenan como problemas JIT. Otras cosas a tener en cuenta:

  • Recolección de basura: ¿está asignando memoria durante el procesamiento de audio? Si está creando una gran cantidad de basura, o incluso objetos que sobreviven a una colección Gen 0, esto podría causar picos noticibles. Parece que estás haciendo algún tipo de asignación previa, pero ten cuidado con las asignaciones ocultas en el código de la biblioteca (¡incluso un bucle foreach puede asignar!)

  • Denominaciones. Existe un problema con ciertos tipos de procesadores cuando se trata de números de coma flotante muy pequeños que pueden causar picos de CPU. Ver http://www.musicdsp.org/files/denormal.pdf para más detalles.

Editar:

Incluso si usted no desea utilizar NGen, al menos comparar una versión NGen'd para que pueda ver lo que hace la diferencia JITing

+1

Interesante. No tenía ni idea de que los denormales eran un golpe de velocidad tan monstruoso. –

2

Si cree que está siendo afectado por JIT, precompile su aplicación con NGEN y vuelva a ejecutar las pruebas. No hay sobrecarga de JIT en el código que ha sido compilado por NGEN. Si aún ve picos en la aplicación NGEN, entonces sabrá que no son causados ​​por JIT.

Cuestiones relacionadas