2009-09-07 4 views
9

¿Cómo puede la velocidad de salida ser más alta que la velocidad de escritura del disco duro?Perl: escribir misterio de la velocidad?

Actualización 1: He cambiado la siguiente:

  1. desactivado antivirus. Ningún cambio.

  2. Se insertó un nuevo disco físico y se usó la primera partición para la prueba. (El disco para la prueba inicial estaba en la última partición , separada de la partición del sistema, pero en el mismo disco físico). Resultado: hay la misma patrón cíclico, pero el sistema es ya no no responde durante la prueba. La velocidad de escritura es algo mayor (podría deberse al uso de la primera partición y/o ya no interfiera con la partición del sistema ). Conclusión preliminar: hubo algún tipo de interferencia de la partición del sistema .

  3. Instalado 64 bit Perl. Los ciclos se han ido y todo es estable en una escala de tiempo de 2 segundos: 55% de CPU en el núcleo único, velocidad de escritura de aproximadamente 65 MB/s.

  4. intentado en la unidad original con 64 bits Perl. Resultado: en algún punto intermedio. Ciclos de 8 segundos, CPU 20-50%, 35 - 65 MB/seg (en lugar de ciclos profundos de 0-100%, 0 - 120 MB/seg). El sistema solo es levemente insensible. La velocidad de escritura es de 50 MB/seg. Esto apoya la teoría de la interferencia.

  5. Flushing en el script de Perl. No intentado todavía.


OK, tengo más allá de la first hurdle. He escrito un script en Perl que puede generar un archivo de texto muy grande (por ejemplo, 20 GB) y es esencialmente sólo un número de:

print NUMBERS_OUTFILE $line; 

donde $ línea es una cadena larga con un "\ n" al el fin.

Cuando el script Perl comienza la velocidad de escritura es de unos 120 MB/s (coherente entre lo que se calcula por el script, Process Explorer y "IO Bytes de escritura/s" para el proceso de Perl en Monitor de rendimiento.) Y 100 % CPU en el núcleo único en el que se está ejecutando . Este índice es, creo, más alto que velocidad del disco duro.

Luego, después de un tiempo (por ejemplo, 20 segundos y 2,7 ​​GB por escrito) todo el sistema deja de responder y la CPU cae a 0%. Esto último por ej. 30 segundos. La velocidad promedio de escritura en estas dos fases es consistente con la velocidad de escritura de del disco duro. Los tiempos y tamaños mencionados en este párrafo varían mucho de ejecución a ejecución. El rango de 1 GB a 4,3 GB para la primera fase se ha observado hasta el momento. Aquí hay un transcript for the run with 4.3 GB.

Hay varios de estos ciclos para un archivo de texto 9.2 GB generada en la prueba:

Enter image description here

¿Qué está pasando?


completa Perl script y BAT driver script (HTML formateado con la etiqueta pre ). Si las dos variables de entorno MBSIZE y OUTFILE están configuradas, la secuencia de comandos Perl debería poder ejecutar sin modificaciones en otras plataformas que no sean Windows.

Plataforma: Perl 5.10.0 de ActiveState; (inicialmente 32 bit, luego 64 bit); construir 1004. Windows XP x64 SP2, ningún archivo de página, 8 GB de RAM, AMD de cuatro núcleos de CPU, discos duros de 500 GB caviar verde (velocidad de escritura 85 MB/s?).

Respuesta

5

estoy con todos los demás que ya es decir que el problema es buffers llenado y vaciado a continuación.Intente encender autoflush para evitar tener un buffer (en Perl):

#!/usr/bin/perl 

use strict; 
use warnings; 

use IO::Handle; 

my $filename = "output.txt"; 

open my $numbers_outfile, ">", $filename 
    or die "could not open $filename: $!"; 

$numbers_outfile->autoflush(1); 

#each time through the loop should be 1 gig 
for (1 .. 20) { 
    #each time though the loop should be 1 meg 
    for (1 .. 1024) { 
     #print 1 meg of Zs 
     print {$numbers_outfile} "Z" x (1024*1024) 
    } 
} 

tampones puede ser bueno si se va a imprimir un poco, lo hacen trabajar, imprimir un litte, hacer algún trabajo, etc. Pero si Simplemente vas a estar volando datos en el disco, pueden causar un comportamiento extraño. Es posible que también deba deshabilitar el almacenamiento en caché de escritura que está haciendo su sistema de archivos.

+0

Gracias. Ahora probé Perl de 64 bits (vea la pregunta actualizada), pero el próximo paso será intentar encender el autoflush. –

+0

Recuerde, también puede necesitar modificar su sistema de archivos si mantiene los almacenamientos intermedios. –

+1

autoflush hará una llamada al sistema después de cada elemento de impresión. En su ejemplo, el rendimiento será bueno porque es de 1 MB a la vez. Pero si imprime 'a', 'b', 'c', 'd' será muy malo porque son cuatro llamadas al sistema de un char cada ... tenga cuidado con eso. –

5

Todos los datos se almacenan en caché en el búfer antes de que se layed eficazmente en el disco físico. Un búfer del sistema, otro dentro del propio disco (un búfer de 32 MB probablemente). Mientras llene esos búferes, su programa se ejecutará a toda velocidad y 100% de CPU. Una vez que los búferes están llenos, su programa puede esperar al disco, que es mucho, mucho más lento que la memoria y los búferes, y esta espera le hace dejar de consumir toda esta CPU.

Tal vez pueda hacer que su código "espere el disco" desde el principio, usando algún Perl equivalente a fflush().

+0

Espero que haya almacenamientos intermedios de archivos. Pero no varios GB de tamaño (?) –

+4

En los sistemas linux, los búferes suelen estar configurados para extenderse a casi toda la memoria RAM libre. –

+0

No usa Linux ... –

4

Tal vez el SO está escribiendo en el disco lo más rápido posible (85 MB/s) y está colocando el exceso de 35 MB/s en un búfer, y cuando se llena, pausa la aplicación para vaciar el búfer. Dado que el buffer se drena a 85 MB/s, esperaría que tome 35/85 = ~ 0.4 veces más para drenar que llenar. Eso es ampliamente compatible con su gráfico, si entiendo lo suficiente.

Se puede estimar el tamaño del búfer como el producto del tiempo de pausa y la velocidad del disco.

3

¡Mira el gráfico! La línea verde indica la longitud promedio de la cola del disco. En un momento, obtiene un pico y la CPU pasa a 0 después. IO Writes también pasa a 0. Vuelve a la normalidad hasta que se muestra un segundo pico. Entonces las escrituras de CPU e IO vuelven a la normalidad. Luego, tanto IO como CPU vuelven a caer, para volver a subir en el siguiente pico de Queue. Y de nuevo hacia abajo, luego de nuevo ...

Podría ser que el disco está haciendo las escrituras físicas en ese momento. Sin embargo, también podría ser que el sistema esté realizando una validación de disco en ese momento, leyendo el dat que acaba de escribir para validar las escrituras, asegurándose de que los datos estén escritos correctamente.

Otra cosa que noto es el tamaño 2,7 GB. Como está ejecutando esto en un sistema Windows, me vuelvo un poco sospechoso ya que esa es la cantidad de memoria que Windows puede manejar, como un proceso de 32 bits. El Windows de 64 bits proporcionará a la aplicación hasta 3 GB de RAM (un poco menos) pero luego necesita liberarla nuevamente. Es posible que desee usar Process Explorer para verificar la cantidad de RAM en uso y la cantidad de lecturas de IO.

Y tal vez utilizar una versión de 64 bits de Perl ...

+0

En cuanto a 2,7 GB: no sé si es posible más de 3 GB, pero ya puede suceder a 1 GB. Por ejemplo, justo antes de escribir esto lo ejecuté de nuevo y la primera fase finalizó en 1,2 GB (en algún lugar entre 1139 MB y 1273 MB). –

+0

¿A qué te refieres con la cantidad de RAM? Monto para el proceso de Perl "Bytes privados" para el proceso de Perl se mantiene constante en 4 MB durante la ejecución. Aproximadamente 6.3 GB de RAM es gratis cuando se inicia el script. –

+0

Acabo de intentar otra carrera. Esta vez, la primera fase finalizó en aproximadamente 4.3 GB (en algún lugar entre 4.19 GB y 4.41 GB [4288.3 MB; 4513.7 MB]). Aquí hay una transcripción de la ejecución: http://www.pil.sdu.dk/1/until2039-12-31/PerlPerfTranscript_2009-09-07b.txt –

Cuestiones relacionadas