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 :

Lire de gros fichier rapidement


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éprouvé
    Homme Profil pro
    Ingénieur réseau et sécurité / Consultant
    Inscrit en
    Août 2005
    Messages
    1 068
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur réseau et sécurité / Consultant
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2005
    Messages : 1 068
    Par défaut Lire de gros fichier rapidement
    Bonjour,

    je souhaite lire des fichiers très rapidement en C. Le fichier fait environ 10 GB et je souhaite le lire le plus rapidement possible. Voici une partie de 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
    //open read only
    	fichierR = fopen(fileNameR,"rb");
     
    	if(fichierR != NULL){
    		gettimeofday(&tv1, NULL); //get the current time
    		do{
    			//read 8191 bytes of the file and store them into buffer
    			v = fread(buffer, blk_size-1, 1, fichierR);
    		}while(v != 0);
     
    		gettimeofday(&tv2, NULL);
     
    		//Compute the time to read the file
    		duration = (float) (tv2.tv_usec - tv1.tv_usec)/1000000 + (float) (tv2.tv_sec - tv1.tv_sec);
     
    		//Compute the read speed
    		readSpeed = (size*8)/duration;
     
    		printf ("Read time = %.15f seconds\n", duration);
    		printf ("Read speed = %f %s/s\n", readSpeed/(float)divCoef, units);
     
    	}else{
    		printf("Error during opening file %s\n",fileNameR);
    	}
    J'ai un SSD en sata 3 qui lit normalement a 4.4 Gb/s mais ici j'obtiens que 3.4 Gb/s sous linux alors que si j'utilise un programme de test de SSD j'obtiens bien les 4.4 Gb/s. J'aimerai savoir comment améliorer mon code.

    merci de votre aide.

    PS: Linux Ubuntu 12.04 LTS 64bits, GCC, SSD Vertex 3 MI,

  2. #2
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Par défaut
    Utilise read() plutôt que fread() pour bypasser la libc. Lit des blocs plus gros pour limiter le nombre de syscalls.

  3. #3
    Modérateur
    Avatar de gangsoleil
    Homme Profil pro
    Manager / Cyber Sécurité
    Inscrit en
    Mai 2004
    Messages
    10 150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Manager / Cyber Sécurité

    Informations forums :
    Inscription : Mai 2004
    Messages : 10 150
    Par défaut
    Bonjour,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    //read 8191 bytes of the file and store them into buffer
    Pourquoi lire par tranches de 8Ko, alors que ton fichier va faire 10Go ? As-tu essaye de diminuer drastiquement le nombre de lectures (10 lectures de 1Go par exemple) ?

    Enfin, quel est le but ? Lire le plus rapidement possible, ou bien tu fais un traitement derriere ?
    "La route est longue, mais le chemin est libre" -- https://framasoft.org/
    Les règles du forum

  4. #4
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 502
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 502
    Billets dans le blog
    1
    Par défaut
    Quelqu'un a parlé d'un gain de vitesse important avec mmap il y a peu : http://www.developpez.net/forums/d12...x/mmap-munmap/

    @matafan : fread() du C fait appel ) read() de l'OS en fait ?

  5. #5
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Par défaut
    Oui, fread() fait du read() en ajoutant un système de bufferisation.

  6. #6
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 407
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 407
    Par défaut
    Citation Envoyé par gangsoleil Voir le message
    Pourquoi lire par tranches de 8Ko, alors que ton fichier va faire 10Go ? As-tu essaye de diminuer drastiquement le nombre de lectures (10 lectures de 1Go par exemple) ?
    1Go ce n'est pas dit que ça tienne (ça dépend du layout mémoire), mais pour un fichier de cette taille je préconiserai au moins 100Mo.

    Et surtout pas 100Mo -1! Si tu veux te ménager la place pour un caractère nul, fais toi un buffer de 100Mo +1, mais ne change pas la taille des lectures: Il vaut mieux que ça reste un multiple de la taille de secteur.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  7. #7
    Membre éprouvé
    Homme Profil pro
    Ingénieur réseau et sécurité / Consultant
    Inscrit en
    Août 2005
    Messages
    1 068
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur réseau et sécurité / Consultant
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2005
    Messages : 1 068
    Par défaut
    merci tous pour vos réponses. Voici les modifications que j'ai faite à mon code.

    Citation Envoyé par gangsoleil Voir le message
    Bonjour,

    As-tu essaye de diminuer drastiquement le nombre de lectures (10 lectures de 1Go par exemple) ?
    Oui j'ai même essayé de lire des blocs de la même taille que le buffer mais sa change rien.

    Un gros buffer.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    static char buffer[128*1024*1024]; //default buffer 128MB
    Ouverture avec open, en limitant les effets de cache par la même occasion
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int fd = open(fileNameR,O_RDONLY,O_DIRECT|O_LARGEFILE);
    Je sais que ne pas utiliser le cache n'est pas une bonne chose mais le but est pour le moment de tester la vitesse de lecture d'un disque SSD en PCI-Express qui est censé fournir 16 Gb/s de lecture.

    Pour la lecture, je peux faire varier la taille des blocs mais j'ai pas remarqué de différences majeurs.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    v = read(fd,buffer,blk_size);
    Qu'en pensez-vous ? J'ai aussi vu la fonction readv() qui permet d'utiliser plusieurs buffer ? Pensez-vous que sa pourrais aider ?

    Niveau processeur, il n'est pas du tout surchargé donc je ne sais pas ou est le soucis...

    ps: je suis en train de faire le même code avec mmap si jamais.

  8. #8
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Par défaut
    Ce que tu peux faire aussi c'est lire directement le device, ce qui bypassera la couche filesystem.

Discussions similaires

  1. Lire de gros fichiers de logs
    Par johnnyjohnny dans le forum Général Python
    Réponses: 15
    Dernier message: 18/06/2008, 10h38
  2. Lire des gros fichiers
    Par alain123 dans le forum Entrée/Sortie
    Réponses: 3
    Dernier message: 04/09/2007, 09h16
  3. [Delphi 7] Lire un gros fichier
    Par bibi26 dans le forum Delphi
    Réponses: 5
    Dernier message: 05/03/2007, 22h30
  4. [XML]lire un gros fichier de format xml et l'envoyer
    Par diamonds dans le forum XML/XSL et SOAP
    Réponses: 1
    Dernier message: 17/10/2006, 15h33
  5. Peut-on lire des gros fichiers(100k) avec "TClientSocke
    Par Fred LEM dans le forum C++Builder
    Réponses: 3
    Dernier message: 20/12/2004, 14h41

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