2008-09-24 13 views
12

Nuestra aplicación tarda mucho más tiempo en iniciarse después de un reinicio (arranque en frío) que si ya se hubiera abierto una vez (inicio en caliente).Comparación del arranque en frío con el arranque en caliente

La mayoría (si no todos) la diferencia parece provenir de la carga de archivos DLL, cuando los archivos DLL se encuentran en páginas de memoria en caché se cargan mucho más rápido. Intentamos usar ClearMem para simular el reinicio (ya que lleva mucho menos tiempo que en realidad reiniciar) y obtuvimos resultados mixtos, en algunas máquinas parecía simular un reinicio de manera muy consistente y en otras no.

Para resumir mis preguntas son:

  1. ¿Ha tenido diferencias en el tiempo de lanzamiento entre los arranques en frío y caliente?
  2. ¿Cómo ha estado con estas diferencias?
  3. ¿Conoces alguna manera de simular de manera confiable un reinicio?

Editar:

Aclaraciones de Comentarios:

  • La aplicación es principalmente C++ nativo con un poco de .NET (el primer ensamblado de .NET que se carga paga por el CLR).
  • Estamos buscando mejorar el tiempo de carga, obviamente, hicimos nuestra parte de perfiles y mejoramos los puntos de acceso en nuestro código.

Algo que me olvidé de mencionar fue que obtuvimos algunas mejoras volviendo a basar todos nuestros binarios para que el cargador no tenga que hacerlo en el momento de la carga.

+0

Motti, ¿tiene alguna idea nueva para simular un reinicio? Estoy buscando así para nuestra gran aplicación, pero no encontré una manera sólida –

+0

@Dbger, lo siento, no hice ningún progreso adicional en esto, pasé a diferentes problemas. Buena suerte. – Motti

Respuesta

3

¿Cómo perfiló su código? No todos los métodos de creación de perfiles son iguales y algunos encuentran los puntos de conexión mejores que otros. ¿Estás cargando muchos archivos?Si es así, la fragmentación del disco y el tiempo de búsqueda podrían entrar en juego.

Tal vez incluso pegando información de temporización básica en el código y escribir en un archivo de registro y examinar los archivos en inicio frío/caliente ayudará a identificar donde la aplicación está pasando su tiempo.

Sin más información, me inclino por el sistema de archivos/caché de disco como la diferencia probable entre los dos entornos. Si ese es el caso, entonces debe pasar menos tiempo cargando archivos por adelantado, o encontrar formas más rápidas de cargar archivos. Un ejemplo (que puede no aplicarse) es que si está cargando la carga de archivos de datos binarios es combinarlos todos en un solo archivo, haga una slerp de todo el archivo en la memoria en una sola lectura, y luego analice sus contenidos. Menos sesiones de disco y tiempo dedicado a la lectura fuera del disco. De nuevo, quizás eso no se aplica. No conozco ninguna herramienta para borrar el disco/caché del sistema de archivos, pero podrías escribir una aplicación rápida para leer un montón de archivos no relacionados fuera del disco para provocar que el sistema de archivos/caché del disco se cargue con información diferente.

+0

Analizaré los archivos DLL unificadores que suenan como una opción prometedora. – Motti

+2

A partir de los síntomas, parece que el código consume más tiempo que el tiempo de ejecución del código de inicialización. En ese caso, un generador de perfiles no ayudará (excepto, posiblemente, para ver si ha progresado en la mejora del tiempo de carga). Reduzca la cantidad de archivos DLL que se deben cargar, hágalos más pequeños, vuelva a establecer una base para que no haya superposición. El acceso al registro también puede ser doloroso en un arranque nuevo. –

6

En cuanto a la simulación de reinicios, ¿ha considerado ejecutar su aplicación desde virtual PC? Al usar la virtualización, puede replicar convenientemente un conjunto de condiciones una y otra vez.

También consideraría algún tipo de profiling app para detectar el bit de código que causa el retraso de tiempo, y luego hacer la llamada de juicio sobre cuánto de ese código es realmente necesario, o si se puede lograr de una manera diferente.

+1

El problema con las máquinas virtuales (utilizamos VMWare no Virtual PC) es que equilibran la carga de todo (incluida la CPU) y los números que recibíamos no eran consistentes. – Motti

+1

Punto tomado, aunque sospecho que al replicar los reinicios estás persiguiendo síntomas en lugar de causas raíz. El hecho es que hay algo que consume demasiado tiempo en una DLL, independientemente de cuándo se carga, los reinicios difíciles simplemente exacerban el problema. Estoy seguro de que una herramienta de creación de perfiles ayudará aquí –

+0

:) Gracias por las aclaraciones adicionales –

4

Sería difícil simular realmente un reinicio en el software. Cuando reinicia, todos los dispositivos en su máquina obtienen su bit de reinicio afirmado, lo que debería causar la pérdida de toda la memoria de todo el sistema.

En una máquina moderna, tiene memoria y cachés en todas partes: está el subsistema VM que almacena páginas de memoria para el programa, luego tiene el sistema operativo almacenando el contenido de los archivos en la memoria caché, entonces ha obtuve el búfer en disco de sectores en el disco duro mismo. Probablemente pueda restaurar los cachés del sistema operativo, pero ¿el búfer en el disco de la unidad? No sé de una manera.

0

Una forma de hacer que las aplicaciones comiencen el arranque en frío más rápido (más o menos) es utilizado por, p. Adobe Reader, cargando algunos de los archivos al inicio, ocultando así el inicio en frío de los usuarios. Esto solo se puede usar si el programa no debe iniciarse de inmediato.

Otra nota, es que .NET 3.5SP1 supuestamente ha mejorado mucho la velocidad de arranque en frío, aunque no puedo decir cuánto.

+0

Esto es malo, y una de las razones por las que no tengo Adobe Reader instalado. –

0

Podrían ser los NIC (tarjetas LAN) y su aplicación depende de ciertos otros servicios que requieren que la red aparezca. Por lo tanto, es posible que el perfil de su aplicación por sí solo no le diga esto, pero debe examinar las dependencias de su aplicación.

+0

Este no es el caso, somos puramente del lado del cliente. – Motti

2

@Morten Christiansen dijo:

Una forma de hacer que las aplicaciones iniciar de arranque en frío más rápido (más o menos) se utiliza por ejemplo Adobe Reader, cargando algunos de los archivos al inicio, ocultando así el inicio en frío de los usuarios. Esto solo se puede usar si el programa no debe iniciarse de inmediato.

Eso hace que el cliente paga para inicializar nuestra aplicación en cada arranque, incluso cuando no se usa, yo realmente no me gusta esa opción (tampoco Raymond).

2

Una forma exitosa de acelerar el inicio de la aplicación es cambiar las DLL a la carga de retraso. Este es un cambio de bajo costo (algunos cambios en la configuración del proyecto) pero puede hacer que el arranque sea mucho más rápido. Después, ejecute depends.exe en el modo de creación de perfiles para averiguar qué DLL se cargan durante el inicio de todos modos, y revertir el retraso de carga en ellos. Recuerde que también puede demorar la carga de la mayoría de las DLL de Windows que necesita.

2

Una técnica muy efectiva para mejorar el tiempo de arranque en frío de la aplicación es optimizar el orden de enlace de funciones.

El enlazador de Visual Studio le permite pasar un archivo que enumera todas las funciones en el módulo que está siendo vinculado (o solo algunas de ellas, no tiene que ser todas), y el enlazador colocará esas funciones a continuación el uno al otro en la memoria.

Cuando se inicia la aplicación, normalmente hay llamadas a las funciones de inicio en toda la aplicación. Muchas de estas llamadas se realizarán en una página que aún no está en la memoria, lo que provocará un error de página y una búsqueda de disco. De ahí viene el inicio lento.

Optimizando su aplicación para que todas estas funciones estén juntas puede ser una gran victoria.

Consulte Optimización guiada de perfil en Visual Studio 2005 o posterior. Una de las cosas que PGO hace por usted es ordenar enlaces de función.

Es un poco difícil trabajar en un proceso de compilación, porque con PGO debe vincular, ejecutar la aplicación y luego volver a vincular con la salida del perfil ejecutado.Esto significa que su proceso de compilación necesita tener un entorno de tiempo de ejecución y hacer frente a la limpieza después de compilaciones incorrectas y todo eso, pero el rendimiento suele ser 10 o más veces más rápido y sin cambios de código.

Hay algo más de información sobre el PGO aquí:

http://msdn.microsoft.com/en-us/library/e7k32f4k.aspx

+0

Gracias, lo comprobaré. Por cierto, cuando dices 10+ ¿te refieres a 10%? – Motti

1

Como alternativa a la función de lista de orden, apenas grupo del código que se llamará dentro de las mismas secciones:

#pragma code_seg(".startUp") 
//... 
#pragma code_seg 

#pragma data_seg(".startUp") 
//... 
#pragma data_seg 

Se debe ser fácil de mantener a medida que cambia el código, pero tiene el mismo beneficio que la lista de orden de funciones.

No estoy seguro de si la lista de orden de funciones también puede especificar variables globales, pero use este #pragma data_seg simplemente funcionaría.

0

Si su aplicación no es muy complicada, puede copiar todos los archivos ejecutables a otro directorio, debería ser similar a un reinicio. (Cortar y pegar parece que no funciona, Windows es lo suficientemente inteligente como para saber que los archivos se mueven a otra carpeta está en la memoria)

Cuestiones relacionadas