Principiante para ver: la optimización del tiempo de inicio del sistema Linux

  
                  

(1) El primero es rastrear y analizar el proceso de arranque de Linux, generando un informe detallado del tiempo de arranque.


La forma más sencilla y factible es agregar marcas de tiempo a toda la información del núcleo del proceso de arranque a través de la función PrintkTime, que es conveniente para el análisis de resumen. PrintkTime fue originalmente un parche de kernel proporcionado por CELF, que se incorporó oficialmente en el kernel estándar en versiones posteriores de Kernel 2.6.11. Por lo tanto, puede habilitar esta función directamente en la nueva versión del kernel. Si su kernel de Linux no puede actualizarse a la versión 2.6.11 por algún motivo, puede modificar o descargar directamente los parches proporcionados por CELF: http://tree.celinuxforum.org/CelfPubWiki/PrintkTimes


El método para habilitar la función PrintkTime es muy simple, solo agregue "tiempo" a los parámetros de inicio del kernel. Por supuesto, también puede elegir especificar directamente "Mostrar información de tiempo en printks" en "Piratería de núcleo" al compilar el kernel para forzar una marca de tiempo para la información del kernel para cada arranque. Este enfoque tiene otro beneficio: puede obtener toda la información sobre el kernel antes de analizar los parámetros de inicio. Por lo tanto, elegí el último método.


Cuando se complete la configuración anterior, reinicie Linux y luego envíe la información de arranque del kernel al archivo con el siguiente comando:


dmesg -s 131072 > ktime


Luego use un script "show_delta" (ubicado en la carpeta de scripts del código fuente de Linux) para convertir el archivo de salida anterior al formato de visualización de incremento de tiempo:


/usr /src /Linux-x.xx.xx /scripts /show_delta ktime > dtime


De esta forma, obtendrá un informe detallado sobre el consumo de tiempo de arranque de Linux.


(2) Luego, usaremos este informe para averiguar el proceso que requiere relativamente tiempo en el inicio.


Debe quedar claro que no hay una correspondencia necesaria entre el incremento de tiempo en el informe y la información del kernel. El consumo en tiempo real debe analizarse desde la fuente del kernel.


Esto no es difícil para un amigo que está un poco familiarizado con la programación, porque el incremento de tiempo es solo la diferencia de tiempo entre las llamadas a printk dos veces. En términos generales, durante el proceso de inicio del kernel, después de completar algunas tareas que llevan mucho tiempo, como crear un índice hash, un dispositivo de hardware de sondeo, etc., el resultado será impreso por printk. En este caso, el incremento de tiempo a menudo refleja el proceso correspondiente a la información. Requiere mucho tiempo, pero a veces, el kernel inicia el proceso correspondiente después de llamar a la información de salida de printk, luego el consumo de tiempo del proceso correspondiente de la información del kernel en el informe corresponde al incremento de tiempo de la siguiente línea y, a veces, el consumo de tiempo En un período de tiempo indeterminado entre la salida de la información del núcleo, dichos incrementos de tiempo pueden no reflejarse en absoluto en la información del núcleo.


Por lo tanto, para determinar con precisión el verdadero consumo de tiempo, necesitamos analizar el código fuente del kernel. Cuando sea necesario, por ejemplo, en el tercer caso anterior, debe insertar impresiones de printk en el código fuente para determinar con mayor precisión el proceso de consumo de tiempo real.


El siguiente es el análisis de inicio del kernel de Linux después de mi último corte:


El tiempo total de inicio del kernel: 6.188s


Consumo de teclas Parte del tiempo:

1) 0.652s - Temporizador, IRQ, Caché, inicialización de partes del núcleo como Mem Pages

2) 0.611s - Sincronización del núcleo y del reloj RTC

3 0.328s - Calcular retraso de calibración (consumo total de 4 núcleos de CPU)

4) 0.144s - Calibrar reloj APIC

5) 0.312s - Calibrar costo de migración

6) 3.520s - Inicialización de Intel E1000 NIC


A continuación, cada parte se analizará y resolverá una por una.


(3) A continuación, realice una suboptimización específica.


CELF ha propuesto un conjunto de soluciones de optimización de inicio para Linux incorporado que se utiliza en electrónica de consumo, pero debido a que está orientado a diferentes aplicaciones, solo podemos aprender parcialmente de su experiencia y apuntarnos a nosotros mismos. Haz un análisis específico y prueba el problema.


La inicialización de las partes clave del kernel (Timer, IRQ, Cache, Mem Pages ...) actualmente no es una solución de optimización confiable y factible, por lo que no se considera.


Para el 2 y 3 de los resultados del análisis anterior, CELF tiene un esquema de optimización especial: "RTCNoSync" y "PresetLPJ".


La primera es más fácil de implementar al enmascarar la sincronización del reloj RTC durante el inicio o al poner este proceso después del inicio (dependiendo de la necesidad de la precisión del reloj de la aplicación). Necesito parchar el kernel. Parece que el trabajo actual de CELF es simplemente eliminar el proceso, y no implementa el procesamiento "dormitado" de la sincronización del reloj RTC mencionado. Por esta razón, esta optimización no se ha introducido en mi solución por un tiempo (después de todo, el tiempo que ha traído ha alcanzado el "segundo nivel"), continúe prestando atención.


Este último omite el proceso de cálculo real al obligar a especificar el valor de LPJ en los parámetros de inicio, que se basa en el hecho de que el valor de LPJ no cambia en las mismas condiciones de hardware. Por lo tanto, después de registrar el valor de "Calibrating Delay" en la información del kernel después del inicio normal, puede forzar que el valor LPJ se especifique en los parámetros de inicio de la siguiente forma:


lpj = 9600700


Los 4 y 5 de los resultados del análisis anterior son todos parte de la inicialización de SMP, por lo que no están en el alcance de la investigación CELF (¿tal vez habrá MP4 de múltiples núcleos en el futuro? ...), y solo puede ser autosuficiente. Después de estudiar el código de inicialización de SMP, encontré que el "Costo de migración" también puede omitir el tiempo de calibración de una manera predeterminada como "Retraso de calibración". El método es similar, y finalmente se agregó en los parámetros de inicio del kernel:


migration_cost = 4000,4000


Y la optimización de la inicialización del controlador NIC de Intel es más problemática, aunque también es de código abierto Sin embargo, leer el controlador de hardware no es mejor que leer el código general de C. Además, la modificación de "optimización" basada en esa comprensión superficial también es difícil de proteger. Basado en consideraciones de confiabilidad, finalmente me di por vencido en este camino después de que ambos intentos fracasaran. Luego, para un ángulo de pensamiento diferente, puede aprender de la idea de "inicialización paralela" de CELF en el esquema "ParallelRCScripts", compilar el controlador NIC de forma independiente en los módulos y cargarlos en el script de inicialización de forma sincronizada con otros módulos y aplicaciones, eliminando así el inicio del bloqueo de Probe. El impacto del tiempo. Teniendo en cuenta que la inicialización de la aplicación también puede usar la red, en nuestro entorno de hardware real, solo se utiliza eth0 para el aprovisionamiento, por lo que se debe contar el tiempo de 0,3 segundos de la primera inicialización del puerto de red.


Además de los puntos de optimización mencionados anteriormente en mi solución, CELF también propone optimizaciones específicas en las que podría estar interesado, como:


ShortIDEDelays: acorta el tiempo de detección de IDE (no uso el disco duro en mi aplicación, por lo que no puedo usarlo)

KernelXIP: ejecuta el kernel directamente en ROM o Flash (considerando el factor de compatibilidad, no se usa)

IDENoProbe - Omita el puerto IDE de los dispositivos no conectados

OptimizeRCScripts - Optimice el script linuxrc en initrd (usé BusyBox para un linuxrc más conciso)


Además de otros escenarios de optimización que aún se encuentran en la etapa prevista, los amigos interesados ​​pueden visitar la Wiki de Desarrolladores de CELF para obtener más información.


(4) Resultados de optimización


Después de la optimización especial anterior y la reducción de la redundancia de los scripts inittab y rcS, el tiempo de inicio de todo el kernel de Linux es de 6.188 antes de la optimización. s cae a los 2.016 finales. Si no contiene la inicialización de eth0, solo necesita 1.708s (la inicialización de eth0 puede ser paralela al middleware del sistema y algunas cargas de aplicaciones), que básicamente logra el objetivo establecido. En cooperación con Kexec, el tiempo de reinicio causado por la falla del software puede reducirse considerablemente, y la confiabilidad del producto se mejora efectivamente.

Copyright © Conocimiento de Windows All Rights Reserved