GNU/Linux >> Tutoriales Linux >  >> Linux

¿La CPU es gratuita, pero el script Bash no utiliza todos los recursos de la CPU?

Ejecuté un script simple para generar un archivo csv grande (10000000 líneas) con 6 campos en los que algunos campos cambiaron en cada línea/fila, usando un while círculo. La máquina tenía todas las (32) CPU libres, gran cantidad de RAM (~31 Gb) también estaba libre.

Cronometré el guión con el comando

/usr/bin/tiempo -v script bash.01.sh

Después de correr durante aproximadamente 2 horas, obtuve las siguientes estadísticas:

Comando cronometrado:“bash script.01.sh”
Tiempo del usuario (segundos):1195.14
Tiempo del sistema (segundos):819.71
Porcentaje de CPU que obtuvo este trabajo:27%
Tiempo transcurrido (reloj de pared) (h:mm:ss o m:ss):2:01:10
Tamaño promedio de texto compartido (kbytes):0
Tamaño promedio de datos no compartidos (kbytes) ):0
Tamaño promedio de pila (kbytes):0
Tamaño promedio total (kbytes):0
Tamaño máximo del conjunto residente (kbytes):4976
Tamaño promedio del conjunto residente (kbytes) ):0
Fallos de página mayores (que requieren E/S):0
Fallos de página menores (recuperación de un marco):3131983488
Cambios de contexto voluntarios:22593141
Cambios de contexto involuntarios:10923348
Intercambios:0
Entradas del sistema de archivos:0
Salidas del sistema de archivos:2182920
Mensajes de socket enviados:0
Mensajes de socket recibidos:0
Señales entregadas:0
Tamaño de página (bytes):4096
Estado de salida:0

Quiero saber por qué mi script usó solo el 27% de la CPU. El disco IO no era mucho en absoluto (se vio en la salida de vmstat). Entonces, ¿qué causó la restricción? ¿El código en el script?

Aquí está el guión:

#!/usr/bin/env bash
number=1

while [[ $number -lt 10000001 ]] ; do  
    fname="FirstName LastName $"
    lname=""  
    email="[email protected]"  
    password="1234567890"  
    altemail="[email protected]"  
    mobile="9876543210"      

    echo "$fname,$lname,$email,$password,$altemail,$mobile" >> /opt/list.csv
    number=$(expr $number + 1)  
done  

Respuesta aceptada:

Usando strace , vi que la línea

number=$(expr $number + 1)

provoca una bifurcación, búsqueda de ruta y ejecución de expr . (Estoy usando bash 4.2.45 en Ubuntu). Esa sobrecarga del sistema de archivos, el disco y el proceso hizo que bash solo obtuviera alrededor del 28 % de la CPU.

Cuando cambié esa línea para usar solo operaciones integradas de shell

((number = number + 1))

bash usó alrededor del 98% de la CPU y el script se ejecutó en media hora. Esto fue en un Celeron de 1,5 GHz de una sola CPU.

El script tal como está no hace nada que se ejecute en paralelo, por lo que tener 32 CPU libres no ayudará mucho. Sin embargo, ciertamente puede paralelizarlo, por ejemplo, dividiéndolo en 10 bucles de 1 millón de iteraciones que se ejecutan en paralelo, escribiendo en 10 archivos diferentes y luego usando cat para combinarlos.

El siguiente programa de muestra fue agregado por @Arthur2e5:

max=1000000 step=40000 tmp="$(mktemp -d)"
# Spawning. For loops make a bit more sense in a init-test-incr pattern.
for ((l = 0; l < max; l += step)); do (
    for ((n = l + 1, end = (step + l > max ? max : step + l);
      n <= end; n++)); do
        # Putting all those things into the `buf` line gives you a 1.8x speedup.
        fname="FirstName LastName \$"
        lname=""  
        email="[email protected]"  
        password="1234567890"  
        altemail="[email protected]"  
        mobile="9876543210"
        buf+="$fname,$lname,$email,$password,$altemail,$mobile"$'\n'
    done
    printf '%s\n' "$buf" > "$tmp/$l" ) &
done # spawning..
wait
# Merging. The filename order from globbing will be a mess,
# since we didn't format $l to some 0-prefixed numbers.
# Let's just do the loop again.
for ((l = 0; l < max; l += step)); do
    printf '%s\n' "$(<"$tmp/$l")" >> /opt/list.csv
done # merging..
rm -rf -- "$tmp" # cleanup

Linux
  1. ¿Cómo depurar un script Bash?

  2. Bash Echo ¿La línea de comando se ejecutó en la propia línea de comando (no en un script)?

  3. ¿La variable Curl Outfile no funciona en Bash Script?

  4. ¿Por qué el archivo de traducción de Bash no contiene todos los textos de error?

  5. El script Bash imprime Command Not Found en líneas vacías

35 ejemplos de secuencias de comandos Bash

Cómo ejecutar un script Bash

¿El comando Rm en Bash Script no funciona con variables?

¿Gui o simple Bash Script para acelerar la CPU?

El comando Conda funciona en el símbolo del sistema pero no en el script bash

¿Por qué Bash está en todas partes (en la mayoría, si no en todas, las distribuciones de Linux)?