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

C Discussion :

fseek ou fread avec -lpthread : baisse de perfs


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Modérateur
    Avatar de dinobogan
    Homme Profil pro
    ingénieur
    Inscrit en
    Juin 2007
    Messages
    4 073
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations professionnelles :
    Activité : ingénieur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 4 073
    Par défaut fseek ou fread avec -lpthread : baisse de perfs
    Bonjour,

    Sur une machine IBM AIX 6, compilateur xlc 11.0, j'ai une grosse application mono-thread qui traite énormément de données.

    Maintenant, le code doit utiliser une lib qui intègre un mutex. Le programme est maintenant compilé avec la lib pthread. Le temps de traitement est à présent environ doublé (il passe à 1 heure).

    J'ai réussi à isoler et reproduire le problème. Cela vient des accès fichiers avec fread, fwrite et fseek.

    Voici un exemple pour reproduire le 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
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <errno.h>
     
    int main()
    {
            FILE * fichier = fopen( "mon_fichier.bin", "w" );
     
            if( fichier == NULL ) { printf( "fopen: %s\n", strerror( errno ) ); exit( 1 ); }
     
            for( int i = 0 ; i < 4000000 ; ++i )
            {
                    fseek( fichier, 0, SEEK_SET );
            }
     
            printf( "ok\n" );
            exit( 0 );
    }
    Si je compile avec "xlc -O2 temps_pthread.c", ça prend 5 s.
    Mais si je compile avec "xlc -O2 -lpthread temps_pthread.c", ça prend 6 s.

    Comment expliquer cette différence de temps d'exécution ?
    Quel argument ajouter à xlc pour ne plus avoir de différence de temps ?
    J'ai éplucher la doc de xlc, passé plusieurs heures à faire des recherches sur le net, mais je suis à cours d'idées.

    Merci.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java
    Que la force de la puissance soit avec le courage de ta sagesse.

  2. #2
    Membre actif
    Avatar de fmdao
    Profil pro
    Formateur en informatique
    Inscrit en
    Novembre 2010
    Messages
    90
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Loire (Auvergne)

    Informations professionnelles :
    Activité : Formateur en informatique

    Informations forums :
    Inscription : Novembre 2010
    Messages : 90
    Par défaut
    une idée :

    ces fonctions ne sont pas identiques en monothread et en multithread.

    "This function locks out other threads during execution and is therefore thread-safe."

  3. #3
    Membre Expert Avatar de jabbounet
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juin 2009
    Messages
    1 909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 909
    Par défaut
    Si tu es en recherche de performance sur la lecture de fichier, tu peux regarder du coté des méthodes alternative:

    il existe des comparaisons en l'utilisation de mmap et fread/fseek par exemple.
    Après cela de ton application surtout du nombre et de la taille des fichiers des fichiers à lire

    par exemple:
    http://lemire.me/blog/archives/2012/...tream-or-mmap/
    http://agenthunts.blogspot.fr/2009/0...readwrite.html

  4. #4
    Modérateur
    Avatar de dinobogan
    Homme Profil pro
    ingénieur
    Inscrit en
    Juin 2007
    Messages
    4 073
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations professionnelles :
    Activité : ingénieur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 4 073
    Par défaut
    Merci pour ces infos.

    Mon programme doit traiter plusieurs fichiers de plusieurs Go chacun : ils contiennent chacun un seul type de structure (au sens C). Pour chaque fichier, il doit trier les données.
    Pour chaque fichier, voici les étapes :
    1. charger un giga de données en RAM : un seul fread
    2. trier le tableau
    3. écrire les données sur disque dans un fichier temp : un seul fwrite
    4. si le fichier d'origine est terminé, arrêter là
    5. charger un giga de données depuis le fichier d'origine : un seul fread
    6. trier le tableau
    7. faire un merge structure par structure entre le tableau en RAM et le fichier temp : autant de fread que de structures dans le fichier temporaire, et autant de fwrite que de structures dans le fichier en cours de merge et le tableau en RAM
    8. reprendre à l'étape 1


    Pour le plus gros fichier (105 millions de structures pour 4 Go), le trie prend moins de 5 minutes sans la lib pthread à la compilation, et 10 minutes avec la lib pthread à la compilation.
    Je suis conscient que c'est le merge entre le tableau en RAM et le fichier temp qui pose problème, puisqu'on se retrouve avec plusieurs centaines de millions de fread et fwrite. Mon petit programme de test dans le premier post démontre que le temps d'exécution est augmenté avec l'ajout de pthread en compilation.
    Avec pthread, sans aucune fonction de cette librairie utilisée, j'imagine que le compilateur décide malgré tout de mettre en thread-safe les fread et fwrite, ce qui augmente leur temps d'appel.

    J'ai aussi tester de mettre des gros buffer sur fread et fwrite avec setvbuf, mais ça ne change rien. Et c'est logique, puisque cela semble être les appels à ces fonctions qui sont protégés, et non l'usage du disque.

    En fait, il suffirait que le buffer soit au dessus des fread/fwrite. Avec setvbuf, on a : fread -> buffer -> disque. Il faudrait : buffer -> fread -> disque.
    C'est exactement ce que fait mmap. J'ai bon ?

    Je vais donc faire des tests avec mmap, sans passer par fread et fwrite.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java
    Que la force de la puissance soit avec le courage de ta sagesse.

  5. #5
    Membre actif
    Avatar de fmdao
    Profil pro
    Formateur en informatique
    Inscrit en
    Novembre 2010
    Messages
    90
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Loire (Auvergne)

    Informations professionnelles :
    Activité : Formateur en informatique

    Informations forums :
    Inscription : Novembre 2010
    Messages : 90
    Par défaut
    il n'y a pas un fread_nolock ?

  6. #6
    Modérateur
    Avatar de dinobogan
    Homme Profil pro
    ingénieur
    Inscrit en
    Juin 2007
    Messages
    4 073
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations professionnelles :
    Activité : ingénieur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 4 073
    Par défaut
    Non, pas disponible sur Unix AIX. D'après mes recherches, c'est pour du C++ sur Windows.

    Depuis hier, j'ai développé et testé une petite "classe" qui fonctionne très bien et a même amélioré un peu les performances.
    Mes différentes fonctions de lecture/écriture passent d'abord par un buffer, puis appellent les fonctions bas niveau read et write. Avec un buffer à 1 Mo, c'est nickel.
    J'ai donc refait le fonctionnement de fread et fwrite mais sans les protections multi-thread.

    J'ai continué aussi à me documenter, et j'ai compris qu'il est logique que le compilateur ajoute toutes les protections nécessaires lorsqu'on lui ajoute la lib pthread, quand bien même le programme serait en pur mono-thread.

    C'est donc résolu, merci !
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java
    Que la force de la puissance soit avec le courage de ta sagesse.

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

Discussions similaires

  1. probléme avec fread et/ou fseek
    Par doumo dans le forum MATLAB
    Réponses: 16
    Dernier message: 22/12/2008, 17h15
  2. Access violation avec fseek
    Par baleine dans le forum C
    Réponses: 7
    Dernier message: 18/03/2005, 16h41
  3. Probleme de perf avec File::Find::name;
    Par Ludo167 dans le forum Modules
    Réponses: 6
    Dernier message: 14/07/2004, 11h31
  4. Pb de perf avec upper
    Par superfly dans le forum Administration
    Réponses: 7
    Dernier message: 22/03/2004, 17h08
  5. Probleme avec fseek
    Par Bjorn dans le forum C
    Réponses: 5
    Dernier message: 04/08/2002, 07h17

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