sistema servidores mantenimiento los explotación dominar comandos avanzados avanzada administración administracion linux performance arm

dominar - linux administración avanzada mantenimiento y explotación de los servidores pdf



La utilidad "superior" de Linux en ARM informa números que hemos verificado que están equivocados. ¿Por qué? (2)

Tenemos una placa integrada basada en ARM9 que ejecuta Linux 2.6.32.20. El dispositivo es una cámara de video cuyo hardware de captura / compresión asociado coloca los datos en una entrada fifo en la memoria ARM a la que el ARM accede luego desde el espacio del usuario. También tenemos un controlador para este codificador para control de alto nivel.

Un hilo en el código de nivel de aplicación comprueba este espacio de usuario fifo y cuando hay datos lo envía a través de un socket. Para evitar la sobrecarga de este hilo que necesita sondear el espacio de usuario fifo para los datos, tenemos una llamada de lectura () al controlador muy simple, que en realidad simplemente funciona hasta que haya datos en el fifo (nada es realmente "leído" en el buffer provisto en la llamada a read ()). Esta llamada de lectura () luego regresa y el hilo procede a leer los datos de la fifo hasta que esté vacía y luego se pone de nuevo llamando a la llamada de lectura falsa ().

Este sistema es bastante eficiente, medido por la cantidad de transmisiones de red que pueden transmitirse antes de que se detecten caídas de cuadros. Pero hemos determinado que el uso de la llamada de lectura falsa () hace que la utilidad "superior" de Linux informe sobre el uso de una gran CPU por nuestra aplicación.

Hemos creado 2 versiones de la aplicación, que funciona como arriba y la otra que es idéntica, excepto que nunca llama a la lectura falsa () sino que en su lugar sondea la fifo con intercalaciones de llamadas a usleep (). Cuando observamos el uso de la CPU según lo informado por "arriba" para los 2 casos cuando cada uno envía 5 secuencias, obtenemos:

1) versión de lectura (): CPU 12%
2) versión de usleep (): CPU 4%

Por supuesto, las encuestas en realidad son menos eficientes y si ignoramos lo que dice "arriba" y en su lugar solo medimos cuántas transmisiones de red simultáneas pueden transmitir las 2 versiones antes de que veamos caídas de cuadros, la versión 1 gana.

Hemos verificado que la llamada de lectura () anterior funciona correctamente. Si algún error da como resultado que la llamada a read () retorne inmediatamente, incluso cuando no haya datos en el fifo, entonces el hilo terminaría haciendo un costoso sondeo continuo. Pero este no es el caso; la llamada a read () hace que el hilo se ejecute exactamente 30 veces por segundo como debería.

Pensamos que podría haber algún atajo en nuestra versión de busybox de juguete de "top", pero no estos resultados están en los números sin procesar en / proc // stat que usa la parte superior para calcular los números que se muestran.

Este problema debe ser una limitación de cómo el kernel de Linux recoge los números que se muestran en / proc // stat.

Si alguien entiende por qué debería ser así, por favor, apúntame en la dirección correcta. ¡Gracias!


PUEDO GARANTIZAR que la parte superior no te está mintiendo. Si dice que su proceso está usando el 12% de la CPU, está usando el 12% de la CPU. No hay dos formas de eso.

Obviamente, llamar a los usuarios a dormir no llevará mucho tiempo, ya que hace que el proceso se quede dormido durante (al menos) el tiempo requerido. Eso es probablemente 100 ciclos por llamada para dormir. Read hace mucho más que eso, así que no me sorprende que tome más tiempo de CPU para hacer eso, especialmente si lo haces mucho.

Read will:

  1. Verifique que su mango sea válido.
  2. Verifique que el puntero del buffer y la longitud sean válidos.
  3. Copie la longitud del espacio de usuario al espacio del kernel.
  4. Inserte los datos leídos en estructuras de datos adecuadas.
  5. Busque los identificadores relevantes y el controlador para emitir la solicitud.
  6. Emita la solicitud de lectura a su controlador.
  7. El controlador duerme el proceso [suponiendo que no hay datos disponibles].
  8. El conductor despierta el proceso [cuando hay datos disponibles].
  9. Copie los datos de la longitud de lectura en el espacio del usuario.
  10. Regrese a la persona que llama.

Compara eso con nosotros dormidos:

  1. Ve a dormir.
  2. Despierta.
  3. Regresar al usuario

De coruse "ir a dormir" no es una función trivial, y el despertar tampoco es trivial. Pero son las mismas operaciones, y durante el sueño, el proceso no usa CPU.

Podrías fácilmente calcular cuánto sobrecarga hay en una lectura leyendo desde / dev / zero y durmiendo entre ellos. /dev/zero es un dispositivo que regresa inmediatamente con un buffer lleno de ceros.

Alternativamente, puede intentar usar algo como oprofile para hacer un análisis de rendimiento y ver dónde se gasta el tiempo.

Pero estoy bastante seguro de que tu top no miente.


De hecho, "garantía" es una palabra demasiado fuerte para usar aquí. Actualmente estoy probando 2 tableros basados ​​en ARM diferentes, usando núcleos 3.8 y 3.7 y AMBOS están reportando cosas extrañas en la parte superior. Uno está utilizando el kernel común que la compañía envió, y Arch-Linux por el otro. No creo que estos núcleos hayan sido "pirateados" de ninguna manera. El hardware simplemente no parece estar jugando bien. Uno informa que usa 0% de CPU para cada proceso, aunque el total en la parte superior muestra 50% de inactividad. El otro muestra un proceso relacionado con el controlador dma siempre utilizando el 100% de la CPU. Entonces, en mi experiencia muy limitada, creo que el problema ha sido el mejor.