Supongamos que quiero encontrar todas las coincidencias en el archivo de texto comprimido:
$ gzcat file.txt.gz | pv --rate -i 5 | grep some-pattern
pv --rate
utilizado aquí para medir el rendimiento del tubo. En mi máquina es de aproximadamente 420Mb / s (después de la descompresión).
Ahora estoy tratando de hacer grep paralelo usando GNU paralelo.
$ gzcat documents.json.gz | pv --rate -i 5 | parallel --pipe -j4 --round-robin grep some-pattern
Ahora el rendimiento se reduce a ~ 260Mb / s. Y lo que es un parallel
proceso más interesante en sí mismo es usar mucha CPU. Más que grep
procesos (pero menos que gzcat
).
EDITAR 1 : he probado diferentes tamaños de bloque ( --block
), así como diferentes valores para -N
/ -L
opciones. Nada me ayuda en este punto.
¿Qué estoy haciendo mal?
fuente
--pipe
es ineficiente? Quiero decir, ¿es algún tipo de problema fundamental o más de implementación específica?--pipe
cada byte tiene que pasar por el proceso único, que tiene que hacer un poco de procesamiento en cada byte. El--pipepart
proceso central nunca ve la mayoría de los bytes: son procesados por trabajos generados. Como son bastantes líneas el cuello de botella--pipe
, agradecería a un codificador C / C ++ que reescribiera la parte que luego se ejecutaría para las personas que tienen el compilador C en su camino.grep es muy efectivo: no tiene sentido ejecutarlo en paralelo. En su comando, solo la descompresión necesita más CPU, pero esto no puede ser paralelo.
Dividir la entrada por paralelo necesita más CPU que obtener líneas coincidentes por grep.
El cambio de situación si desea usar en lugar de grep algo que necesita mucha más CPU para cada línea, entonces el paralelo tendría más sentido.
Si desea acelerar esta operación, mire dónde hay cuellos de botella, probablemente sea descompresión (luego ayuda a usar otra herramienta de descompresión o mejor CPU) o - leer desde el disco (luego ayude a usar otra herramienta de descompresión o un mejor sistema de disco).
Según mi experiencia, a veces es mejor usar lzma (-2 por ejemplo) para comprimir / descomprimir archivos, tiene una compresión más alta que gzip, por lo que es mucho menos lo que se necesita leer en el disco y la velocidad es comparable.
fuente
La descompresión es el cuello de botella aquí. Si la descompresión no está paralelizada internamente, no la logrará usted mismo. Si tiene más de un trabajo como ese, entonces, por supuesto, ejecútelos en paralelo, pero su tubería por sí sola es difícil de paralelizar. Dividir una secuencia en secuencias paralelas casi nunca vale la pena, y puede ser muy doloroso con la sincronización y la fusión. A veces solo tiene que aceptar que múltiples núcleos no ayudarán con cada tarea que esté ejecutando.
En general, la paralelización en shell debería estar principalmente en el nivel de procesos independientes.
fuente
parallel
. Estoy de acuerdo en que ciertamente es en el primer caso (sin paralelo), pero en el segundo (con paralelo) el cuello de botella está en el lado paralelo. Esto se desprende de la observación de que el rendimiento se reduce significativamente según lo medido porpv
. Si el cuello de botella está en descompresión, el rendimiento no cambiará lo que agregue a la tubería. Supongo que es una definición muy intuitiva del rendimiento, lo que limita más el rendimiento.parallel
puede escribir en su tubería. En este caso, la mayoría de losgrep
procesos simplemente esperan obtener más, mientrasparallel
trabajan las 24 horas para multiplexar los bloques en varias tuberías (que son operaciones de E / S adicionales e incluso pueden bloquear la descompresión si el búfer está lleno). ¿Intentaste también jugar con el--block
parámetro? Su valor predeterminado es que1M
hasta que un grep obtenga1M
datos, el resto casi seguramente ya está terminado. Por lo tanto, volvemos al hecho de que no tiene sentido paralelizar esto.-N
/-L
opciones. Parece que las opciones predeterminadas están muy cerca del óptimo local que he experimentado :)pv
(contime
). De esta manera puede ver si enpv
sí mismo lo está ralentizando. Si es así,parallel
copiar datos en tuberías es definitivamente una sobrecarga adicional. Y, en cualquier caso, estoy bastante seguro de quegrep
es casi en tiempo real en este caso, especialmente si el patrón es una cadena simple sin mucho retroceso. Además,parallel
intercalará y desordenará lasgrep
salidas.pv
no causa el problema, gracias por el consejo.