9
votes

Perl: Mystère de vitesse d'écriture?

Comment le taux de sortie peut-il être supérieur au taux d'écriture du disque dur?

update 1 : J'ai changé ce qui suit:

  1. a été désactivé antivirus. Pas de changement.

  2. insère nouveau disque physique et utilisé la première partition pour le test. (Le disque pour le test initial était sur le dernière partition, séparée de la partition système, mais sur le même disque physique.). Résultat: il y a le même motif cyclique, mais le système est plus insensible pendant le test. La vitesse d'écriture est un peu plus élevé (pourrait être due à l'utilisation du premier partition et / ou sans interférence avec le système cloison). Conclusion préliminaire: Il y avait une sorte d'interférence de la partition système.

  3. installé 64 bits perl. Les cycles sont partis et Tout est stable sur une scène de 2 secondes: 55% de CPU sur Le noyau unique, vitesse d'écriture d'environ 65 Mo / s.

  4. essayé sur le lecteur d'origine avec 64 bits perl. Résultat: quelque part entre les deux. Cycles de 8 secondes, CPU 20-50%, 35 - 65 MB / SEC (au lieu de cycles profonds de 0 à 100%, 0 - 120 Mo / sec). Le système n'est que légèrement insensible. La vitesse d'écriture est de 50 Mo / sec. Cela prend en charge la théorie des interférences.

  5. rinçage dans le script Perl. Pas encore essayé.


    OK, j'ai passé le Premier obstacle . J'ai écrit un Perl script qui peut générer un très grand fichier texte (par exemple 20 Go) et est essentiellement un certain nombre de: xxx

    où $ ligne est une chaîne longue avec un "\ n" à la fin.

    lorsque le script PERL Démarre le taux d'écriture est d'environ 120 Mo / s (cohérent entre ce qui est calculé par le script, Explorateur de processus et "io écrire des octets / sec" pour le processus Perl dans le moniteur de performance.) et 100% cpu sur le noyau unique est en cours d'exécution. Ce taux est, je crois, plus haut que l'écriture Vitesse du disque dur.

    Puis après un certain temps (par exemple 20 secondes et 2,7 Go écrites) L'ensemble du système devient très insensible et la CPU goutte à 0%. Ce dernier pour E.G. 30 secondes. La vitesse d'écriture moyenne sur ces deux phases est compatible avec la vitesse d'écriture de le disque dur. Les temps et tailles mentionnés dans cette Le paragraphe varie beaucoup de courant à courir. La fourchette 1 gb à 4,3 Go pour la première phase a été observée jusqu'à présent. Voici un Transcription pour la course avec 4,3 Go .

    Il existe plusieurs de ces cycles pour un fichier texte de 9,2 Go généré dans le test:

     Entrez la description de l'image ici

    Qu'est-ce qui se passe?


    Full Script Perl et Script de pilote BAT (HTML formaté avec le pré-tag). Si les deux variables d'environnement mbsize et Outfile est configuré alors le script Perl doit pouvoir fonctionner inchangé sur d'autres plates-formes que Windows.

    Plate-forme: Perl 5.10.0 à partir de l'activation; (initialement 32 bits, plus tard 64 bits); construire 1004. Windows XP x64 SP2, sans page de page, 8 Go de RAM, CPU de noyau AMD Quad, Disques durs du caviar vert 500 Go (vitesse d'écriture 85 MB / s?).


0 commentaires

4 Réponses :


5
votes

Toutes les données sont mises en cache dans des tampons avant d'être effectuées efficacement sur le disque physique. Un tampon du système, un autre à l'intérieur du disque lui-même (un tampon de 32 Mo. probablement). Pendant que vous remplissez ces tampons, votre programme fonctionne à pleine vitesse et à 100% de la CPU. Une fois que les tampons sont complets, votre programme attendra le disque, ce qui est beaucoup plus lent que la mémoire et les tampons, et cette attente vous fait arrêter de consommer tout ce processeur.

Peut-être que vous pouvez faire votre code "attendre le disque" à partir du démarrage, en utilisant certains Perl équivalent à fflush () . .


2 commentaires

Je m'attends à ce qu'il y ait des tampons de fichiers. Mais pas plusieurs GB en taille (?)


Sur les tampons de systèmes Linux sont généralement configurés pour s'étendre à presque tous les béliers gratuits.



4
votes

Peut-être que le système d'exploitation écrit sur le disque aussi vite que possible (85 Mo / s) et met l'excès de 35 Mo / s dans un tampon, et lorsqu'il se remplit, est une pause de l'application pour affleurer le tampon. Étant donné que le tampon est drainé à 85 Mo / s, vous vous attendez à ce qu'il prenne 35/85 = ~ 0,4 fois plus de temps pour se débrouiller à remplir. C'est globalement compatible avec votre graphique, si je plie suffisamment.

Vous pouvez estimer la taille du tampon comme le produit du temps de pause et de la vitesse de disque.


0 commentaires

3
votes

Regardez le graphique! La ligne verte indique la longueur moyenne de la file d'attente de disque. À un moment donné, cela obtient un sommet et le processeur va ensuite à 0. IO écrit également à 0. Il remonte à la normale jusqu'à ce qu'un deuxième pic soit montré. Ensuite, la CPU et l'IO écrit revenir à la normale. Ensuite, Io et CPU abandonnent à nouveau à nouveau, pour augmenter à nouveau au plus prochain sommet de la file d'attente. Et encore bas, puis à nouveau ...

Cela pourrait être que le disque fait les écritures physiques à ce moment-là. Cependant, il pourrait également s'agir du fait que le système effectue une validation de disque à ce moment-là, en lisant le dat, il vient d'écrire pour valider les écrivies, en veillant à ce que les données sont écrites correctement.

Une autre chose que je remarque est la taille de 2,7 Go. Puisque vous l'exécutez sur un système Windows, je deviens un peu méfiant car c'est à peu près la quantité de mémoire que Windows peut gérer, comme processus de 32 bits. Les fenêtres 64 bits fourniront l'application jusqu'à 3 Go de RAM (un peu moins), mais elle doit ensuite le relâcher. Vous voudrez peut-être utiliser l'explorateur de processus pour vérifier la quantité de RAM en cours d'utilisation et la quantité de lecture IO.

et peut-être utiliser une version Perl de 64 bits ...


9 commentaires

En ce qui concerne 2,7 Go: je ne sais pas si plus de 3 Go est possible, mais cela peut arriver déjà à 1 Go. Par exemple, juste avant d'écrire cela, je le faisais à nouveau et que la première phase s'est terminée à 1,2 Go (quelque part entre 1139 MB et 1273 Mo).


Qu'entendez-vous par quantité de RAM? Montant pour le processus PERL? "Les octets privés" pour le processus Perl restent constants à 4 Mo pendant la course. Environ 6,3 Go de RAM est libre lorsque le script est démarré.


Je viens d'essayer une autre course. Cette fois, la première phase s'est terminée à environ 4,3 Go (quelque part entre 4,19 Go et 4,41 Go [4288,3 Mo; 4513,7 MB]). Voici une transcription de la course: PIL. sdu.dk/1/until2039-12-31/perlperftranscript_2009-09-07b. TXT


Je vais essayer d'installer la version 64 bits de Perl de l'activer et de le tester.


Le problème avec l'explorateur de processus est que le système devient si insensible qu'il n'y a pas de mises à jour d'écran dans l'explorateur de processus. Le moniteur Performance cesse également de mettre à jour et je ne sais pas si cela échantillonnait correctement pendant la période insensible.


Un processus de 32 bits ne sera pas en mesure d'utiliser plus de 3 Go de Windows. Un GB est toujours réservé aux fenêtres et une partie de la mémoire sera utilisée par Perl elle-même, plus certaines données. Il se peut que certains compléments / plugin allouent cette RAM sans signaler cela à votre graphique. Il semble que cela suffit de remplir sa propre mémoire tampon en mémoire avant de l'écrire sur le disque, bien que le disque semble signaler écrire IO.


La version 64 bits, si disponible, pourrait être plus optimale pour un système de 64 bits. Rien ne garantit que cela se comportera mieux, mais si c'est quelque chose qui utilise la RAM pour une mémoire tampon ou autre chose, vous aurez au moins un tampon beaucoup plus grand puisque la version 64 bits sera en mesure d'utiliser tous, tandis que la version 32 bits est limité...


J'ai essayé la version 64 bits maintenant (voir question mise à jour). C'est vraiment mieux. Mais ce serait bien de savoir exactement pourquoi.


Eh bien, la version 64 bits est capable d'utiliser beaucoup plus de mémoire que la version 32 bits. Il se pourrait qu'il y ait une sorte de tampon de la mémoire tampon quelque part dans la RAM. Comme test, désactivez le fichier d'échange. Ou tous les fichiers de swap si vous avez plusieurs! Ce n'est pas pratique mais l'effet peut indiquer un problème lié à la mémoire. (Retournez-les après le test!)



5
votes

Je suis avec tout le monde qui dit que le problème est des tampons remplissant puis vidant. Essayez d'allumer autoflush pour éviter d'avoir un tampon (à 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)
    }
}


3 commentaires

Merci. J'ai maintenant essayé 64 bits Perl (voir question mise à jour), mais l'étape suivante consistera à essayer d'allumer l'autoflush.


N'oubliez pas que vous devrez peut-être également modifier votre système de fichiers s'il empêche les tampons.


Autoflush fera un appel système après chaque élément d'impression. Dans votre exemple, les performances seront bonnes parce que c'est 1 Mo à la fois. Mais si vous imprimez 'A', 'B', 'C', "D" Ce sera très mauvais parce que c'est quatre appels système d'un caractère chacun ... attention à cela.