IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Modules Perl Discussion :

Optimiser l'utilisation d'un processeur multi-core


Sujet :

Modules Perl

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Février 2005
    Messages
    85
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 85
    Points : 62
    Points
    62
    Par défaut Optimiser l'utilisation d'un processeur multi-core
    Bonjour,

    Je dispose d'un programme perl tout simple qui filtre un fichier pour générer un fichier csv.

    Exemple simplifié:
    12 56 toto 24
    45 55 toto 67
    =>
    12;56;24
    45;55;67

    Je lance ce script sur plusieurs centaines de fichier.
    J'ai migré mon script sur un machine multi-core, malheuresement le script ne tire pas partie de cette puissance, seulement 3% du CPU, ce qui correspond à 1 core (CPU 32 core).
    Je pourrai lancé le script sur 32 fichiers en même temps en shell, et ainsi de suite mais je préférerai lançer 4 scripts en même temps pour utiliser 25%+25%+25%+25% de CPU, et ainsi de suite.

    je ne voudrait pas partir sur une mauvaise piste en utilisant des modules alors que mon besoin est assez simple.
    J'ai vu deux modules
    -thread
    -Parallel::ForkManager:

    Pourriez-vous me conseiller lequel utiliser et la façon de procéder ou au contraire partir sur une autre piste?
    Faut-il lire 1000 lignes les mettre dans un thread, et ainsi de suite jusqu'a 32?

    Cela me parait un peu complexe à mettre en place et j'ai peur de perdre beaucoup de puissance CPU en échange de données au thread.
    Pour info mes fichiers font entre 5Go et 30Go avec de 30 millions à 500 millions de lignes.

    Merci

  2. #2
    Expert confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    3 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 577
    Points : 5 753
    Points
    5 753
    Par défaut
    Une autre option, sans modification de ton application perl, serait de traiter ta liste de fichier à l'aide d'un Makefile, et d'utiliser l'option -j de la commande make.

    Il devrait être assez facile d'écrire le Makefile à l'aide de règles gérériques et d'utiliser les fonctions de Makefile pour générer la liste des cibles à mettre à jour directement dans le Makefile.
    Plus j'apprends, et plus je mesure mon ignorance (philou67430)
    Toute technologie suffisamment avancée est indiscernable d'un script Perl (Llama book)
    Partagez vos problèmes pour que l'on partage ensemble nos solutions : je ne réponds pas aux questions techniques par message privé
    Si c'est utile, say

  3. #3
    Responsable Perl et Outils

    Avatar de djibril
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    19 820
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 19 820
    Points : 499 184
    Points
    499 184
    Par défaut
    Pourquoi ne pas utiliser le module threads. Il est déjà dans le core de Perl.

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Février 2005
    Messages
    85
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 85
    Points : 62
    Points
    62
    Par défaut
    Si j'utilise un Makefile, j'utiliserai toute la puissance CPU donc si je comprend bien?
    J'ai regarder la synthaxe du makefile de php, c'est spécial mais apparament on peut utiliser automake et autoconf pour le générer?

    Concernant le module thread, il va falloir thread(apparament c'est threads avec un t minuscule qu'il faut utiliser) et threads::shared pour partager les infos.
    Donc il faut que j'ajoute un compteur à mon script qui va toutes les 1000 lignes passer un tableau les contenant à un thread, et ainsi de suite jusqu'a 32 et surveiller la fin d'un thread pour lui attribuer 1000 lignes et je continue jusqu'a la fin du fichier.
    Je vais voir cela.
    J'ai vu qu'il y avait des centaines de modules autour de thread...

    Par contre faut-il compiler perl avec le support thread car j'ai ceci (je suis sous solaris 10)? :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ perl -V | grep threads
        usethreads=undef use5005threads=undef useithreads=undef usemultiplicity=undef
    Le script suivant me donne ce résultat :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     $Config{useithreads} or die
          "Recompilez Perl avec les threads activ\351s pour faire tourner ce programme.";
    Recompilez Perl avec les threads activés pour faire tourner ce programme. at 1.pl line 1.

  5. #5
    Expert confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    3 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 577
    Points : 5 753
    Points
    5 753
    Par défaut
    Citation Envoyé par photorelief Voir le message
    Si j'utilise un Makefile, j'utiliserai toute la puissance CPU donc si je comprend bien?
    Avec l'option -j, tu peux spécifier le nombre de processus parallèle que tu souhaites utiliser. Sur un quadri-core, si tu utilises -j 2, tu devrais n'en utiliser que 2.
    J'ai regarder la synthaxe du makefile de php, c'est spécial mais apparament on peut utiliser automake et autoconf pour le générer?
    Makefile de PHP ???
    Je pensais à un Makefile écrit à la main, très simple du style
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SRC = $(wildcard *.txt)
    DST = $(patsubst %.txt, %.out, $(SRC))
     
    all: $(DST)
     
    %.out : %.txt
    	perl my_script.pl $< $@
    Dans cet exemple, my_script.pl prend en 1er paramètre un fichier d'entrée à partir duquel il génère un fichier de sortie fourni en 2e paramètre.

    A lancer par exemple avec
    make -j 2
    Plus j'apprends, et plus je mesure mon ignorance (philou67430)
    Toute technologie suffisamment avancée est indiscernable d'un script Perl (Llama book)
    Partagez vos problèmes pour que l'on partage ensemble nos solutions : je ne réponds pas aux questions techniques par message privé
    Si c'est utile, say

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Février 2005
    Messages
    85
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 85
    Points : 62
    Points
    62
    Par défaut
    Effectivement ta méthode correspond exactement à ce que je veux faire.
    Par compte l'option -j n'hésiste pas sur le make de solaris 10.
    Je vais continuer à chercher, il y a peut être une commande gnumake.

  7. #7
    Expert confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    3 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 577
    Points : 5 753
    Points
    5 753
    Par défaut
    Je te conseille effectivement d'utiliser gnumake... J'ai toujours travaillé avec gmake sous Solaris, le make de Solaris étant moins puissant, si je me souviens bien.
    Plus j'apprends, et plus je mesure mon ignorance (philou67430)
    Toute technologie suffisamment avancée est indiscernable d'un script Perl (Llama book)
    Partagez vos problèmes pour que l'on partage ensemble nos solutions : je ne réponds pas aux questions techniques par message privé
    Si c'est utile, say

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Février 2005
    Messages
    85
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 85
    Points : 62
    Points
    62
    Par défaut
    Rebonjour,

    Avec le makefile, j'ai bien deux processus (j'ai pourtant 8 fichiers .log) dans le répertoire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
       PID USERNAME  SIZE   RSS STATE  PRI NICE      TIME  CPU PROCESS/NLWP       
     12227 MCO_HP   4672K 3680K cpu16    0    0   0:02:20 3.1% checkpoint.pl/1
     12226 MCO_HP   4672K 3680K cpu12    0    0   0:02:20 3.1% checkpoint.pl/1
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    SRC = $(wildcard *.log)
    DST = $(patsubst %.log, %.csv, $(SRC))
     
    #all: 
    #       /data/home/MCO_HP/prefiltrage/checkpoint.pl /data/home/MCO_HP/testdir/PFCI_CMA_20100317005729.log /data/home/MCO_HP/testdir/toto.csv
     
    all: $(DST)
     
    %.csv : %.log
            /data/home/MCO_HP/prefiltrage/checkpoint.pl /data/home/MCO_HP/testdir/$< /data/home/MCO_HP/testdir/$@
    Le make -j 2 lance effectivment en parallèle seulement deux traitements de chaque fichier *.log dans le réperoire mais sur certain fichier, il passe 8h.
    Et j'ai besoin qu'il ne pas qu'une 1h sur chaque fichier max.
    Donc il faut qu'il utilise au moins 8 core en même temps pour traiter un seul fichier.

    J'ai donc essayer le module thread.
    J'ai compilé perl pour activer ithread.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    ./configure -Dusethreads -Dprefix=/usr/local/perl 
    make
    make test => il plante sur un test mais je n'en ait pas tenu compte 
    make install
    Voici mon code, il est encore boiteux, car je voudrais qu'il ne lance que 32 thread et qu'il attende qu'un thread rend la main avant d'en lancer un autre.
    Là il lance des thread à l'infinie.
    Mais le plus gros problème, c'est qu'il n'utilise qu'un seul core pour tous les thread.

    PID USERNAME SIZE RSS STATE PRI NICE TIME CPU PROCESS/NLWP
    10703 MCO_HP 63M 62M cpu16 0 0 0:00:09 1.1% toto.pl/115

    On est à 1,1% alors qu'il a lançé 115 thread.

    Voici mon code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    #!/usr/local/perl/bin/perl
    use warnings;
    use strict;
    use Thread;
     
    sub ProcessLog{
            my $l__line = "";
            my $i = 0;
            my $core=0;
            while ( defined($l__line = <INPUT_FILE>)){
                $i++;
                $core=0;
                if($i==10000){
                    $i=1;
                } 
                if($i==1){ 
                     $core++;
                     my $thr = Thread->new(\&sub1,$l__line);
                     if($core==32){
                         $thr->join;
                     }
                     sub sub1 {
                         print "In the thread\n";
                         my $line=$_[0];
                         #print "LINE:".$line;
                         if ($line ne ""){
                             my($val1,$val2,$val3)=split(/ /,$line);
                             my $l__newLine = $val1.";".$val3;
                             print OUTPUT_FILE $l__newLine."\n";
                             #return($l__newLine."\n");
                         }
                     }
                }
            }
    }
     
    my $l__logInput = $ARGV[0];
    my $l__logOutput = $ARGV[1];
    open(INPUT_FILE, "< $l__logInput") || die "probleme d'ouverture du fichier de lecture\n";
    open(OUTPUT_FILE, "> $l__logOutput") || die "probleme d'ouverture du fichier d ecriture\n";
    &ProcessLog;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    $ /usr/local/perl/bin/perl -V
    Summary of my perl5 (revision 5 version 8 subversion 8) configuration:
      Platform:
        osname=solaris, osvers=2.10, archname=sun4-solaris-thread-multi
        uname='sunos prcsvadm15-new 5.10 generic_127127-11 sun4v sparc sunw,sparc-enterprise-t5120 '
        config_args='-ds -e -Dusethreads -Dprefix=/usr/local/perl'
        hint=recommended, useposix=true, d_sigaction=define
        usethreads=define use5005threads=undef useithreads=define usemultiplicity=define
        useperlio=define d_sfio=undef uselargefiles=define usesocks=undef
        use64bitint=undef use64bitall=undef uselongdouble=undef
        usemymalloc=n, bincompat5005=undef
      Compiler:
        cc='gcc', ccflags ='-fno-strict-aliasing -pipe -Wdeclaration-after-statement -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -DPERL_USE_SAFE_PUTENV -DPERL_USE_SAFE_PUTENV',
        optimize='-O',
        cppflags='-fno-strict-aliasing -pipe -Wdeclaration-after-statement'
        ccversion='', gccversion='3.4.3 (csl-sol210-3_4-branch+sol_rpath)', gccosandvers='solaris2.10'
        intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=4321
        d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16
        ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
        alignbytes=8, prototype=define
      Linker and Libraries:
        ld='gcc', ldflags =' -L/usr/local/lib '
        libpth=/usr/local/lib /usr/lib /usr/ccs/lib
        libs=-lsocket -lnsl -ldl -lm -lpthread -lc
        perllibs=-lsocket -lnsl -ldl -lm -lpthread -lc
        libc=/lib/libc.so, so=so, useshrplib=false, libperl=libperl.a
        gnulibc_version=''
      Dynamic Linking:
        dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags=' '
        cccdlflags='-fPIC', lddlflags='-G -L/usr/local/lib'
     
     
    Characteristics of this binary (from libperl): 
      Compile-time options: MULTIPLICITY PERL_IMPLICIT_CONTEXT
                            PERL_MALLOC_WRAP PERL_USE_SAFE_PUTENV
                            USE_ITHREADS USE_LARGE_FILES USE_PERLIO
                            USE_REENTRANT_API
      Built under solaris
      Compiled at Mar 25 2010 16:39:28
      @INC:
        /usr/local/perl/lib/5.8.8/sun4-solaris-thread-multi
        /usr/local/perl/lib/5.8.8
        /usr/local/perl/lib/site_perl/5.8.8/sun4-solaris-thread-multi
        /usr/local/perl/lib/site_perl/5.8.8
        /usr/local/perl/lib/site_perl
        .
    Pour l'instant je n'ai pas de solution pour utiliser dédier plusieurs coeurs à un seul programme.
    J'ai l'impression que perl n'utilise pas le multithreating.

  9. #9
    Responsable Perl et Outils

    Avatar de djibril
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    19 820
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 19 820
    Points : 499 184
    Points
    499 184
    Par défaut
    il faut utiliser threads et non thread.

  10. #10
    Membre du Club
    Profil pro
    Inscrit en
    Février 2005
    Messages
    85
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 85
    Points : 62
    Points
    62
    Par défaut
    J'ai modifié mon code mais j'ai toujours le même problème.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    #!/usr/local/perl/bin/perl
    use warnings;
    use strict;
    use threads;
     
    sub ProcessLog{
            my $l__line = "";
            my $i = 0;
            my $core=0;
            while ( defined($l__line = <INPUT_FILE>)){
                chomp($l__line);
                $i++;
                $core=0;
                if($i==10000){
                    $i=1;
                } 
                if($i==1){ 
                     $core++;
                     my $thr = threads->new(\&sub1,$l__line);
                     if($core==32){
                         $thr->join;
                     }
                     sub sub1 {
                         #print "In the thread\n";
                         my $line=$_[0];
                         #print "LINE:".$line;
                         if ($line ne ""){
                             my $val1="";
                             my $val2="";
                             my $val3="";
                             if(defined $line){
                                 ($val1,$val2,$val3)=split(/ /,$line);
                             }
                             my $l__newLine = $val1.";".$val3;
                             print OUTPUT_FILE $l__newLine."\n";
                             #return($l__newLine."\n");
                         }
                     }
                }
            }
    }
     
    my $l__logInput = $ARGV[0];
    my $l__logOutput = $ARGV[1];
    open(INPUT_FILE, "< $l__logInput") || die "probleme d'ouverture du fichier de lecture\n";
    open(OUTPUT_FILE, "> $l__logOutput") || die "probleme d'ouverture du fichier d ecriture\n";
    &ProcessLog;

  11. #11
    Membre du Club
    Profil pro
    Inscrit en
    Février 2005
    Messages
    85
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 85
    Points : 62
    Points
    62
    Par défaut
    En fait étant donnée que la lecture du fichier est séquencielle, il y a peut-être un goulot d'étranglement au niveau du disque.
    Comme je lit un ligne, je la traite puis je l'a met dans un fichier de sortie, le CPU n'a pas besoin de plus de puissance pour marcher.
    Il faudrait peut-être que je traite par lot de 10000 lignes dans chaque threads pour surcharger le CPU.

  12. #12
    Membre du Club
    Profil pro
    Inscrit en
    Février 2005
    Messages
    85
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 85
    Points : 62
    Points
    62
    Par défaut
    J'ai résolu mon problème, en passant sur une machine avec de nombreux core, mes scripts se terminent très rapidement.
    Perl aime bien le CPU, le multithreading ne servait à rien.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Les processeurs multi-cores pourraient gagner en performances
    Par Katleen Erna dans le forum Hardware
    Réponses: 0
    Dernier message: 01/02/2011, 18h44
  2. Réponses: 268
    Dernier message: 07/11/2007, 11h11
  3. Benchmark sur processeur multi-core
    Par Charlemagne dans le forum C++
    Réponses: 123
    Dernier message: 16/07/2007, 10h51
  4. Réponses: 5
    Dernier message: 14/04/2007, 14h12
  5. [Weblogic][Tuning] Optimiser l'utilisation du processeur
    Par Jacques - 06 dans le forum Weblogic
    Réponses: 5
    Dernier message: 04/07/2006, 15h07

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo